diff -c -r --new-file ds2.0r26/lib/cmds/admins/mfinger.c ds2.0r29/lib/cmds/admins/mfinger.c *** ds2.0r26/lib/cmds/admins/mfinger.c Mon Nov 7 13:28:38 2005 --- ds2.0r29/lib/cmds/admins/mfinger.c Sat Jul 8 23:30:54 2006 *************** *** 53,58 **** void help() { message("help", "Syntax: \n\n" ! "Allows you to get finger information from a player's site.", this_player()); } --- 53,63 ---- void help() { message("help", "Syntax: \n\n" ! "Allows you to get finger information from a player's site.\n\n" ! "Note: In 1995, you could reliably expect a UNIX machine to cheerfully " ! "respond to a finger request. Now, more than 10 years later, everything " ! "is blocked, firewalled, and hardened. This command is all but useless, " ! "and is kept as a historical curiosity. Any \"bugs\" it contains will " ! "not be fixed.", this_player()); } diff -c -r --new-file ds2.0r26/lib/cmds/common/help.c ds2.0r29/lib/cmds/common/help.c *** ds2.0r26/lib/cmds/common/help.c Sat Mar 11 11:13:28 2006 --- ds2.0r29/lib/cmds/common/help.c Wed Jul 5 00:01:03 2006 *************** *** 16,28 **** mixed cmd(string arg) { object who = previous_object(); int array screen = (who->GetScreen() || ({ 80, 24 })); ! string help; ! if( !arg || arg == "" || arg == "help") { help = HELP_D->GetHelp("help"); write(help); return 1; } if( arg == "index" || HELP_D->GetTopics(arg) ) { if( arg == "index" ) { HelpMenu(); --- 16,35 ---- mixed cmd(string arg) { object who = previous_object(); int array screen = (who->GetScreen() || ({ 80, 24 })); ! string help = ""; ! if( arg == "help") { help = HELP_D->GetHelp("help"); write(help); return 1; } + if( !arg || arg == "") { + if(creatorp(this_player())) help = read_file("/doc/help/creators/creator_general"); + else help = read_file("/doc/help/players/player_general"); + if(!sizeof(help)) help = HELP_D->GetHelp("help"); + write(help); + return 1; + } if( arg == "index" || HELP_D->GetTopics(arg) ) { if( arg == "index" ) { HelpMenu(); diff -c -r --new-file ds2.0r26/lib/cmds/creators/colors.c ds2.0r29/lib/cmds/creators/colors.c *** ds2.0r26/lib/cmds/creators/colors.c Thu Apr 13 21:03:19 2006 --- ds2.0r29/lib/cmds/creators/colors.c Sat Jul 8 23:30:54 2006 *************** *** 6,29 **** int cmd() { write( ! "%^RED%^RED\n" ! "%^GREEN%^GREEN\n" ! "%^ORANGE%^ORANGE\n" ! "%^YELLOW%^YELLOW\n" ! "%^BLUE%^BLUE\n" ! "%^CYAN%^CYAN\n" ! "%^MAGENTA%^MAGENTA\n" ! "%^BLACK%^BLACK\n" ! "%^WHITE%^WHITE\n" ! "%^B_RED%^B_RED\n" ! "%^B_GREEN%^B_GREEN\n" ! "%^B_ORANGE%^B_ORANGE\n" ! "%^B_YELLOW%^B_YELLOW\n" ! "%^B_BLUE%^B_BLUE\n" ! "%^B_CYAN%^B_CYAN\n" ! "%^B_BLACK%^B_BLACK\n" ! "%^B_WHITE%^B_WHITE%^RESET%^\n" ! "%^B_MAGENTA%^B_MAGENTA%^RESET%^\n" ); return 1; } --- 6,33 ---- int cmd() { write( ! "%^RED%^RED\t%%^^RED%%^^\n" ! "%^GREEN%^GREEN\t%%^^GREEN%%^^\n" ! "%^ORANGE%^ORANGE\t%%^^ORANGE%%^^\n" ! "%^YELLOW%^YELLOW\t%%^^YELLOW%%^^\n" ! "%^BLUE%^BLUE\t%%^^BLUE%%^^\n" ! "%^CYAN%^CYAN\t%%^^CYAN%%^^\n" ! "%^MAGENTA%^MAGENTA\t%%^^MAGENTA%%^^\n" ! "%^BLACK%^BLACK\t%%^^BLACK%%^^\n" ! "%^WHITE%^WHITE\t%%^^WHITE%%^^\n" ! "%^B_RED%^B_RED\t%%^^B_RED%%^^\n" ! "%^B_GREEN%^B_GREEN\t%%^^B_GREEN%%^^\n" ! "%^B_ORANGE%^B_ORANGE\t%%^^B_ORANGE%%^^\n" ! "%^B_YELLOW%^B_YELLOW\t%%^^B_YELLOW%%^^\n" ! "%^B_BLUE%^B_BLUE\t%%^^B_BLUE%%^^\n" ! "%^B_CYAN%^B_CYAN\t%%^^B_CYAN%%^^\n" ! "%^B_BLACK%^B_BLACK\t%%^^B_BLACK%%^^\n" ! "%^B_WHITE%^B_WHITE\t%%^^B_WHITE%%^^\n" ! "%^B_MAGENTA%^B_MAGENTA%^RESET%^\n\n" ! "Special tags: %%^^BOLD%%^^ and %%^^FLASH%%^^ and %%^^RESET%%^^\n\n" ! "You can mix and match, for example: \n" ! "%%^^B_RED%%^^%%^^CYAN%%^^%%^^BOLD%%^^%%^^FLASH%%^^Foo!%%^^RESET%%^^:" ! "%^B_RED%^%^CYAN%^%^BOLD%^%^FLASH%^Foo!%^RESET%^" ); return 1; } diff -c -r --new-file ds2.0r26/lib/cmds/creators/margins.c ds2.0r29/lib/cmds/creators/margins.c *** ds2.0r26/lib/cmds/creators/margins.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/cmds/creators/margins.c Wed Jul 5 00:01:03 2006 *************** *** 0 **** --- 1,19 ---- + #include + + inherit LIB_DAEMON; + + mixed cmd(string str) { + return @ENDTEXT + |---------------------------------------------------------------|-------------| + ENDTEXT; + } + + void help() { + write("Syntax: margins\n"); + write(@EndText + This simple command prints a line to help creators when writing + descriptions. It gives a visual indicator of when to stop on + one line and continue on the next. + EndText + ); + } diff -c -r --new-file ds2.0r26/lib/cmds/creators/move.c ds2.0r29/lib/cmds/creators/move.c *** ds2.0r26/lib/cmds/creators/move.c Wed Apr 5 19:33:16 2006 --- ds2.0r29/lib/cmds/creators/move.c Wed Dec 31 19:00:00 1969 *************** *** 1,55 **** - /* /cmds/creators/move.c - * From the Dead Souls V Object Library - * Moves object from one place to another - * created by Descartes of Borg 961008 - * Version: @(#) move.c 1.2@(#) - * Last modified: 96/10/08 - */ - - #include - #include - - inherit LIB_DAEMON; - - mixed cmd(string args) { - object what, destination; - string a, b; - mixed res; - - if( sscanf(args, "%s into %s", a, b) != 2 && - sscanf(args, "%s to %s", a, b) != 2 ) { - return "Syntax: \n\n"; - } - what = to_object(a); - destination = to_object(b); - if( !what ) { - return "Unable to find " + a + "."; - } - if( !destination ) { - return "Unable to find " + b + "."; - } - if( living(what) && living(destination) ) { - return "None of that nonsense."; - } - res = what->eventMove(destination); - if( !res ) { - return "Failed to move " + identify(what) + " into " + - identify(destination) + "."; - } - else if( res != 1 ) { - return res; - } - previous_object()->eventPrint("Moved " + identify(what) + " into " + - identify(destination) + ".", MSG_SYSTEM); - if( living(what) ) { - what->eventDescribeEnvironment(); - } - return 1; - } - - string GetHelp() { - return ("Syntax: \n\n" - "Allows you to move the object you name into the container " - "you name.\n\n" - "See also: trans, expel, goto, return"); - } --- 0 ---- diff -c -r --new-file ds2.0r26/lib/cmds/creators/polyglottize.c ds2.0r29/lib/cmds/creators/polyglottize.c *** ds2.0r26/lib/cmds/creators/polyglottize.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/cmds/creators/polyglottize.c Wed Jul 5 00:01:03 2006 *************** *** 0 **** --- 1,41 ---- + #include + #include + + inherit LIB_DAEMON; + + mixed cmd(string str) { + object target; + + if(!str || str == "") str = "me"; + + if(str == "me") str = this_player()->GetKeyName(); + if(!target = present(str, environment(this_player()))){ + write("They're not here."); + return 1; + } + if(!living(target)) { + write("That's not a living thing."); + return 1; + } + if(creatorp(target) && !archp(this_player()) && + target != this_player()){ + write("That's impolite."); + tell_player(target,capitalize(this_player()->GetKeyName())+ + " just tried to polyglottize you."); + return 1; + } + + target->SetPolyglot(1); + if(target == this_player()) str = "yourself"; + else str = capitalize(str); + write("You polyglottize "+str+"."); + if(target != this_player()) + tell_object(target, capitalize(this_player()->GetKeyName())+" polyglottizes you."); + return 1; + } + + void help() { + message("help", "Syntax: polyglottize \n\n" + "Make the target able to understand all languages.\n\n", + this_player()); + } diff -c -r --new-file ds2.0r26/lib/cmds/creators/transfer.c ds2.0r29/lib/cmds/creators/transfer.c *** ds2.0r26/lib/cmds/creators/transfer.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/cmds/creators/transfer.c Wed Jul 5 00:01:03 2006 *************** *** 0 **** --- 1,59 ---- + /* /cmds/creators/transfer.c + * From the Dead Souls V Object Library + * Moves object from one place to another + * created by Descartes of Borg 961008 + * Version: @(#) transfer.c 1.2@(#) + * Last modified: 96/10/08 + */ + + #include + #include + + inherit LIB_DAEMON; + + mixed cmd(string args) { + object what, destination; + string a, b; + mixed res; + + if(!args || args == ""){ + return "Syntax: \n\n"; + } + + if( sscanf(args, "%s into %s", a, b) != 2 && + sscanf(args, "%s to %s", a, b) != 2 ) { + return "Syntax: \n\n"; + } + what = to_object(a); + destination = to_object(b); + if( !what ) { + return "Unable to find " + a + "."; + } + if( !destination ) { + return "Unable to find " + b + "."; + } + if( living(what) && living(destination) ) { + return "None of that nonsense."; + } + res = what->eventMove(destination); + if( !res ) { + return "Failed to transfer " + identify(what) + " into " + + identify(destination) + "."; + } + else if( res != 1 ) { + return res; + } + previous_object()->eventPrint("Transferred " + identify(what) + " into " + + identify(destination) + ".", MSG_SYSTEM); + if( living(what) ) { + what->eventDescribeEnvironment(); + } + return 1; + } + + string GetHelp() { + return ("Syntax: \n\n" + "Allows you to transfer the object you name into the container " + "you name.\n\n" + "See also: trans, expel, goto, return"); + } diff -c -r --new-file ds2.0r26/lib/cmds/players/biography.c ds2.0r29/lib/cmds/players/biography.c *** ds2.0r26/lib/cmds/players/biography.c Mon Nov 7 13:28:39 2005 --- ds2.0r29/lib/cmds/players/biography.c Wed Jul 5 19:58:18 2006 *************** *** 93,99 **** d2 = ({}); } else { ! x = x/2; d1 = deaths[0..(x-1)]; d2 = deaths[x..]; } --- 93,99 ---- d2 = ({}); } else { ! //x = x/2; d1 = deaths[0..(x-1)]; d2 = deaths[x..]; } *************** *** 123,129 **** col3 = npcs[(2*x)..]; } for(i=0; i= sizeof(col1)) ? "" : col1[i] + " (" + kills[col1[i]] + ")", (i >= sizeof(col2)) ? "" : --- 123,129 ---- col3 = npcs[(2*x)..]; } for(i=0; i= sizeof(col1)) ? "" : col1[i] + " (" + kills[col1[i]] + ")", (i >= sizeof(col2)) ? "" : diff -c -r --new-file ds2.0r26/lib/cmds/players/env.c ds2.0r29/lib/cmds/players/env.c *** ds2.0r26/lib/cmds/players/env.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/cmds/players/env.c Wed Jul 5 00:01:03 2006 *************** *** 0 **** --- 1,19 ---- + #include + + inherit LIB_DAEMON; + + mixed cmd(string args) { + write("Screen: \t\t"+identify(this_player()->GetScreen())); + write("Terminal: \t\t"+this_player()->GetTerminal()); + write("Brief mode: \t\t"+ ( (this_player()->GetBriefMode()) ? "on" : "off" )); + //write("PlayerKill mode: \t"+ ( (this_player()->GetPK()) ? "on" : "off" )); + if(creatorp(this_player())) + write("Debug mode: \t\t"+ ( (this_player()->GetProperty("debug")) ? "on" : "off" )); + return 1; + } + + void help() { + message("help", "Syntax: \n\n" + "Displays your basic interface and play settings. " + + "See also: brief, terminal, screen", this_player()); + } diff -c -r --new-file ds2.0r26/lib/cmds/players/language.c ds2.0r29/lib/cmds/players/language.c *** ds2.0r26/lib/cmds/players/language.c Wed Apr 5 19:33:16 2006 --- ds2.0r29/lib/cmds/players/language.c Wed Jul 5 00:01:03 2006 *************** *** 11,18 **** } write("You speak:"); ! foreach(string key, int val in FluencyMap){ ! write(capitalize(key)+" with "+val+"% proficiency."); } return 1; --- 11,25 ---- } write("You speak:"); ! ! if(this_player()->GetPolyglot()){ ! write("All languages with 100% proficiency."); ! } ! ! else { ! foreach(string key, int val in FluencyMap){ ! write(capitalize(key)+" with "+val+"% proficiency."); ! } } return 1; diff -c -r --new-file ds2.0r26/lib/cmds/players/mudlist.c ds2.0r29/lib/cmds/players/mudlist.c *** ds2.0r26/lib/cmds/players/mudlist.c Tue Mar 28 23:23:40 2006 --- ds2.0r29/lib/cmds/players/mudlist.c Wed Jul 5 19:58:18 2006 *************** *** 100,108 **** list = ({}); foreach(mud, info in borg) list += ({ sprintf("%:-15s %:-6s %:-15s %:-18s %s %d", ! mud, info[8], info[7], info[5], info[1], info[2]) }); list = sort_array(list, 1); ! list = ({ mud_name() + " recognizes " + consolidate(sizeof(borg), "a mud")+ " matching your query: ", "" }) + list; this_player()->eventPage(list); return 1; --- 100,108 ---- list = ({}); foreach(mud, info in borg) list += ({ sprintf("%:-15s %:-6s %:-15s %:-18s %s %d", ! replace_string(mud,"%^","%%^^"), info[8], info[7], info[5], info[1], info[2]) }); list = sort_array(list, 1); ! list = ({ replace_string(mud_name(),"%^","%%^^") + " recognizes " + consolidate(sizeof(borg), "a mud")+ " matching your query: ", "" }) + list; this_player()->eventPage(list); return 1; diff -c -r --new-file ds2.0r26/lib/cmds/players/screen.c ds2.0r29/lib/cmds/players/screen.c *** ds2.0r26/lib/cmds/players/screen.c Mon Nov 7 13:28:39 2005 --- ds2.0r29/lib/cmds/players/screen.c Wed Jul 5 00:01:03 2006 *************** *** 11,21 **** mixed cmd(string args) { int *screen; int h, w; if( args == "" || !args ) ! return "You need to specify both width and height."; if( sscanf(args, "%d %d", w, h) != 2 ) ! return "You need to specify both width and height."; this_player()->SetScreen(w, h); message("system", "Screen set to " + w + " by " + h + ".", this_player()); return 1; --- 11,24 ---- mixed cmd(string args) { int *screen; int h, w; + string chide = "You need to specify both width and height.\n"; + string ret = "Your current settings are: "+ this_player()->GetScreen()[0]; + ret += " "+ this_player()->GetScreen()[1]; if( args == "" || !args ) ! return chide + ret; if( sscanf(args, "%d %d", w, h) != 2 ) ! return chide + ret; this_player()->SetScreen(w, h); message("system", "Screen set to " + w + " by " + h + ".", this_player()); return 1; diff -c -r --new-file ds2.0r26/lib/cmds/players/who.c ds2.0r29/lib/cmds/players/who.c *** ds2.0r26/lib/cmds/players/who.c Wed Feb 22 15:29:49 2006 --- ds2.0r29/lib/cmds/players/who.c Wed Jul 5 00:01:03 2006 *************** *** 6,12 **** #include inherit LIB_DAEMON; - int elderp(object foo); #define SEP repeat_string("*=",39)+"*\n"; --- 6,11 ---- *************** *** 23,30 **** if(!obs[i]->GetInvis()) { if(archp(obs[i])) tmp+="[%^BLUE%^ARCH%^RESET%^]"; else if(creatorp(obs[i]) ) tmp+="[%^CYAN%^WIZ%^RESET%^]"; else tmp+=sprintf("[%d]", obs[i]->GetLevel() ); ! if(elderp(obs[i])) tmp+=" [%^GREEN%^ELDER%^RESET%^]"; if(sizeof(obs[i]->GetShort()) < 50) { tmp+=sprintf(" %s", obs[i]->GetShort()); } --- 22,32 ---- if(!obs[i]->GetInvis()) { if(archp(obs[i])) tmp+="[%^BLUE%^ARCH%^RESET%^]"; else if(creatorp(obs[i]) ) tmp+="[%^CYAN%^WIZ%^RESET%^]"; + else if(avatarp(obs[i]) ) tmp+="[%^GREEN%^AVATAR%^RESET%^]"; + else if(high_mortalp(obs[i]) ) tmp+="[%^GREEN%^HIGH MORTAL%^RESET%^]"; else tmp+=sprintf("[%d]", obs[i]->GetLevel() ); ! if(elderp(obs[i])) tmp+=" [%^YELLOW%^ELDER%^RESET%^]"; ! if(ambassadorp(obs[i])) tmp+=" [%^YELLOW%^AMBASSADOR%^RESET%^]"; if(sizeof(obs[i]->GetShort()) < 50) { tmp+=sprintf(" %s", obs[i]->GetShort()); } *************** *** 54,61 **** return 1; } - int elderp(object ob){ - string str; - str=ob->GetKeyName(); - return member_group(str, PRIV_ELDER); - } --- 56,58 ---- diff -c -r --new-file ds2.0r26/lib/daemon/help.c ds2.0r29/lib/daemon/help.c *** ds2.0r26/lib/daemon/help.c Mon Jan 23 09:03:35 2006 --- ds2.0r29/lib/daemon/help.c Wed Jul 5 00:00:58 2006 *************** *** 438,445 **** help = "Index: %^GREEN%^" + index + "%^RESET%^\n" + "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help; if( file_exists(DIR_RACE_HELP + "/" + topic) ) ! help += read_file(DIR_RACE_HELP + "/" + topic); ! return help; } Error = "No such race exists."; return 0; --- 438,445 ---- help = "Index: %^GREEN%^" + index + "%^RESET%^\n" + "Topic: %^GREEN%^" + topic + "%^RESET%^\n\n" + help; if( file_exists(DIR_RACE_HELP + "/" + topic) ) ! //help += read_file(DIR_RACE_HELP + "/" + topic); ! return help; } Error = "No such race exists."; return 0; diff -c -r --new-file ds2.0r26/lib/daemon/intermud.c ds2.0r29/lib/daemon/intermud.c *** ds2.0r26/lib/daemon/intermud.c Wed Apr 12 23:47:49 2006 --- ds2.0r29/lib/daemon/intermud.c Wed Jul 5 00:00:58 2006 *************** *** 11,16 **** --- 11,17 ---- #else #include + #include #include #include #include *************** *** 31,37 **** Password = 0; Tries = 0; Banned = ([]); - Nameservers = ({ ({ "*yatmim", "149.152.218.102 23" }) }); MudList = new(class list); ChannelList = new(class list); MudList->ID = -1; --- 32,37 ---- *************** *** 40,45 **** --- 40,46 ---- ChannelList->List = ([]); if( file_size( SAVE_INTERMUD __SAVE_EXTENSION__ ) > 0 ) unguarded( (: restore_object, SAVE_INTERMUD, 1 :) ); + Nameservers = ({ ({ "*yatmim", "149.152.218.102 23" }) }); SetNoClean(1); tn("INTERMUD_D reloaded."); SetDestructOnClose(1); *************** *** 73,78 **** --- 74,93 ---- (mapping)SERVICES_D->GetServices(), ([]) }) ), "red");; } + void eventClearVars(){ + if( !((int)master()->valid_apply(({ PRIV_ASSIST, INTERMUD_D }))) ) + error("Illegal attempt to reset intermud: "+get_stack()+" "+identify(previous_object(-1))); + Connected = 0; + Tries = 0; + MudList = new(class list); + ChannelList = new(class list); + MudList->ID = -1; + MudList->List = ([]); + ChannelList->ID = -1; + ChannelList->List = ([]); + save_object(SAVE_INTERMUD); + } + static void eventRead(mixed *packet) { mixed val; string cle; *************** *** 164,169 **** --- 179,185 ---- break; case "chanlist-reply": // if( packet[6] == ChannelList->ID ) return; + tn("chanlist reply: "+identify(packet), "blue"); if( packet[2] != Nameservers[0][0] ) return; ChannelList->ID = packet[6]; foreach(cle, val in packet[7]) { diff -c -r --new-file ds2.0r26/lib/daemon/verbs.c ds2.0r29/lib/daemon/verbs.c *** ds2.0r26/lib/daemon/verbs.c Wed Feb 22 15:29:50 2006 --- ds2.0r29/lib/daemon/verbs.c Sun Jul 9 19:04:26 2006 *************** *** 23,29 **** string verb; int i; - //tc("/daemon/verbs: eventReloadVerbs"); if( arrayp(val) ) verbs = filter(val, (: GetValidVerb($1) :)); else if( stringp(val) ) { if( strlen(val) > 2 && val[<2..] == ".c" ) val = val[0..<3]; --- 23,28 ---- *************** *** 51,56 **** --- 50,63 ---- break; } } + foreach(dir in get_dir(DIR_SECURE_VERBS + "/")) { + dir = DIR_SECURE_VERBS + "/" + dir; + if( file_size(dir) != -2 ) continue; + if( file_exists( dir + "/" + val + ".c") ) { + verbs = ({ dir + "/" + val }); + break; + } + } if( !verbs ) return; } } *************** *** 64,69 **** --- 71,81 ---- if( file_size(dir) == -2 ) verbs += map(get_dir(dir + "/*.c"), (: $(dir) + "/" + $1 :)); } + foreach(dir in get_dir(DIR_SECURE_VERBS + "/")) { + dir = DIR_SECURE_VERBS + "/" + dir; + if( file_size(dir) == -2 ) + verbs += map(get_dir(dir + "/*.c"), (: $(dir) + "/" + $1 :)); + } } i = 0; foreach(verb in verbs) { *************** *** 87,101 **** } string GetErrorMessage(string verb) { - //tc("/daemon/verbs: GetErrorMessage"); if( !Verbs[verb] ) return 0; else return (string)Verbs[verb]->GetErrorMessage(); } int GetValidVerb(string verb) { ! //tc("/daemon/verbs: GetValidVerb: verb: "+verb); ! return !strsrch(verb, DIR_VERBS); ! //key_arr = keys(GetVerbs()); } mapping GetVerbs() { return copy(Verbs); } --- 99,111 ---- } string GetErrorMessage(string verb) { if( !Verbs[verb] ) return 0; else return (string)Verbs[verb]->GetErrorMessage(); } int GetValidVerb(string verb) { ! if(!strsrch(verb, DIR_VERBS) || !strsrch(verb, DIR_VERBS)) return 1; ! else return 0; } mapping GetVerbs() { return copy(Verbs); } diff -c -r --new-file ds2.0r26/lib/doc/CREDITS ds2.0r29/lib/doc/CREDITS *** ds2.0r26/lib/doc/CREDITS Mon May 15 11:27:29 2006 --- ds2.0r29/lib/doc/CREDITS Sat Jul 8 23:30:54 2006 *************** *** 3,22 **** Sine qua non: Descartes, the legion of MudOS developers, and all those coders who toiled at Nightmare, and Lars Pensjö. Direct conributors: Haderach and his clever code and inspiration, Duuk and his willingness to let me poke through his lib and filch code. Great thanks to Marajin for his direct and substantial contribution to the Windows port. Thanks also to the following for code donation, support, and/or contribution: Tim@TimMUD, Manchi, ! Brodbane, Ashon, Shadyman, Jonez, Cecil. Appreciation of: Jayren, Kaylus, Arianrhod, Nosmo, Pyro, Abby, Balmung, Aten, Metiscus, Garfield, Javelin, Alensin, Daelas, ! and Detah for their thoughtful comments and suggestions. Also: Xyzzy He Is Cool --- 3,27 ---- Sine qua non: Descartes, the legion of MudOS developers, and all those coders who toiled at Nightmare, and Lars Pensjö. + Marius for his kind permission to bundle MudOS. Direct conributors: Haderach and his clever code and inspiration, Duuk and his willingness to let me poke through his lib and filch code. Great thanks to Marajin for his direct and substantial contribution to the Windows port. + Much gratitude to Saquivor, for whom a town street is + now named, for getting the Windows socket code working. Thanks also to the following for code donation, support, and/or contribution: Tim@TimMUD, Manchi, ! Brodbane, Ashon, Shadyman, Jonez, Cecil, Daelas. Appreciation of: Jayren, Kaylus, Arianrhod, Nosmo, Pyro, Abby, Balmung, Aten, Metiscus, Garfield, Javelin, Alensin, Daelas, ! Zeus, Dastuun, Detah, and Nulvect for their thoughtful comments and suggestions. + Much gratitude to playtesters: Karri, Aten, Tacitus. + Also: Xyzzy He Is Cool diff -c -r --new-file ds2.0r26/lib/doc/README ds2.0r29/lib/doc/README *** ds2.0r26/lib/doc/README Mon Jan 23 09:17:12 2006 --- ds2.0r29/lib/doc/README Wed Jul 5 00:00:58 2006 *************** *** 6,21 **** safe first, and then restore it after you upgrade. Alternately you may just edit the new mudos.cfg to say what the old one said. ! GENERAL FAQ: http://dead-souls.sourceforge.net/ds-faq.html ! ADMIN FAQ: http://dead-souls.sourceforge.net/ds-admin-faq.html ! ED TUTORIAL: http://dead-souls.sourceforge.net/editor.html ! NEW CREATION SYSTEM: http://dead-souls.sourceforge.net/example.html ! ! The Frontiers LPC Foundation is pleased to present the ! re-release of Dead Souls 2. Please read /doc/SUPPORT for details on the supportability of this software. Note that the Frontiers LPC Foundation does not take --- 6,18 ---- safe first, and then restore it after you upgrade. Alternately you may just edit the new mudos.cfg to say what the old one said. ! GENERAL FAQ: http://dead-souls.net/ds-faq.html ! ADMIN FAQ: http://dead-souls.net/ds-admin-faq.html ! ED TUTORIAL: http://dead-souls.net/editor.html ! NEW CREATION SYSTEM: http://dead-souls.net/example.html Please read /doc/SUPPORT for details on the supportability of this software. Note that the Frontiers LPC Foundation does not take *************** *** 30,49 **** This mudlib is based on that old warhorse. It is entirely free from those copyright problems, and can be shared. ! We felt that too many substandard libs were starting to ! pop up, and that there was a need to bring back some of the old ! LPC magic. In accordance with this wish to cater to the elite, we have ! disabled some intermud channels by default. To enable them, all you ! need to do is add them to yourself with these commands: ! call me->AddChannel("intergossip") ! call me->AddChannel("intercre") ! ! If you want to contribute to the Dead Souls Lib Resurrection ! project, please visit Frontiers MUD and leave some mudmail for ! Cratylus. You can also request to sign up as a lib developer at ! http://sourceforge.net/projects/dead-souls/ ! ! The latest available files will be at http://sourceforge.net/project/showfiles.php?group_id=148388 so check often. Please review /doc/old/README for more historical background. --- 27,34 ---- This mudlib is based on that old warhorse. It is entirely free from those copyright problems, and can be shared. ! The latest files will be at ! http://sourceforge.net/project/showfiles.php?group_id=148388 Please review /doc/old/README for more historical background. diff -c -r --new-file ds2.0r26/lib/doc/RELEASE_NOTES ds2.0r29/lib/doc/RELEASE_NOTES *** ds2.0r26/lib/doc/RELEASE_NOTES Sun Jun 18 16:28:32 2006 --- ds2.0r29/lib/doc/RELEASE_NOTES Sun Jul 9 19:04:27 2006 *************** *** 1,3 **** --- 1,91 ---- + ---- 2.0r29 --- + - Fixed finger daemon to not display ip addresses to players. + - The verb copy now handles relative paths more gracefully. + - LIB_TEACHER can now know all languages with SetAllLanguages(1) + - Standard chairs and beds can no longer be taken when someone is using them. + - Fixed church elevator buttons. + - Fixed problem with "look at pile". + - Fixed problem with examining objects on surfaces. + - It is now also possible to look at things carried by others, + e.g. "look at shirt on fighter". + - Remote finger no longer betrays invisible people. + - Added sefun: alpha_strip + - Room descriptions now indicate which piece of furniture a creature + is resting on, if applicable. + - Objects on surfaces than can be sat or lain in are not visible + or accessible if someone is lying or sitting on that surface. e.g., + you can't examine or get the glasses under your butt on the chair. + - SetMaxHealthPoints now works as one would expect. The kitchen rat + is invincible no more. + - Look at problem fixed. + - Bank tellers (Zoe) now do a better job of retaining the correct + surcharge on currency withdrawals. + - Added /secure/obj/glasses.c as a creation object. Since you wear them, + it's hard to lose them accidentally. Since few things are called "glasses", + they won't get in the way of creating objects. New creators will have them + automatically added to the table in their sample room. + - One may now have a smiley in front of a channel message without + it turning into an emote. + - Fixed a conflict in the parsing system. + - Verbified "force". + - Fixed vendor bugs: appraising at zero, confusion with similar items. + - Beefed up the answers_to sefun, to handle adjectives. + - Fixed a couple of bugs in the lead/follow system. + - Fixed null error when selling to non-vendors. + - Fixed a channel log bug that logged to one of two files for + some channels, depending on whether someone was logged on (!!). + - Fixed bug in meals that prevented empty bottles replacing + full ones. + - Fixed a bug in the MudOS parser that screwed up things with apostrophes. + + ---- 2.0r28 --- + - Fixed minor bug in body.c that interfered with collapsing. + - Fixed message boards. + - Added command: snoopreport + - Fixed bug that caused players to be essentially immortal. + - Player death history is now accurately recorded. + - The command mudlist now ignores colors. + + ---- 2.0r27 --- + - Fixed currency problem in dying NPC's. + - Added commands: env, polyglottize + - Fixed "about" verb. + - Tweaked snoop daemon and snoop objects. + - Added pay-for-lessons feature in language teachers. + - Fixed bug in LIB_EXITS that hosed various things, + including wandering NPC's. + - mv command no longer overwrites an existing destination file. + - Fixed campus rooms with hosed CanReceive()'s that horked logins. + - Turned "move" command into "transfer", to address a conflict with + the "move" verb. - Fixed bug in admintool that prevented assistant admins from + using it. + - Fixed bug in eval that prevented assistant admins from using it. + - i3router: dynamic channel data is now persistent (newly created + channels won't disappear when the router resets). + - i3router: fixed a bug in chanlist-reply that stopped the + channel list being sent to LPUni lib muds. + - Modified install process to handle compiling on Wolfpaw servers. + - Added code example domain that was donated by Daelas @ Moraelinost. + - Added new podium, conference room, and margins command that were + donated by Daelas @ Moraelinost. + - i3router: correct password is now honored. + - Fixed help daemon bug that displayed race help twice. + - QCS: creating an enter no longer wipes exits from an existing + target room. + - Fixed bug in rescue login (Thanks, Nulvect). + - Fixed bug in tell command that mishandled mud name ambiguity. + - Fixed bug in CHAT_D that failed to return remote channel listeners. + - i3router: fixed bug that incorrectly rejected targeted emotes. + - Killing a creature super-ultra-extremely fast no longer + generates multiple corpses. + - QCS: Fixed some money problems with both how much things cost and + how much money they have. + - Modified encumbrance to be rather less cumbersome. + - Mailer default behavior now is to notify you when you receive new + mail. Already created characters do not have this default. + - Fixed opacity problem in worn storage. + - Fixed message board in arch room. + ---- 2.0r26 --- - Plugged some serious security holes ( http://dead-souls.net/news.html#16jun06 ) - Cleaned up some unnecessary call_outs in lib objects. diff -c -r --new-file ds2.0r26/lib/doc/SUPPORT ds2.0r29/lib/doc/SUPPORT *** ds2.0r26/lib/doc/SUPPORT Mon Jan 23 09:17:12 2006 --- ds2.0r29/lib/doc/SUPPORT Wed Jul 5 00:00:58 2006 *************** *** 12,18 **** For your convenience, a telnet room has been added to your mud that can help you connect to Frontiers, so that you may ask for help if you run into trouble. Just enter the telnet room ! west of the wizard hall, and type: connect You may ask questions of creators there, but don't be offended if they are more interested in building --- 12,18 ---- For your convenience, a telnet room has been added to your mud that can help you connect to Frontiers, so that you may ask for help if you run into trouble. Just enter the telnet room ! west and north of the wizard hall, and type: connect You may ask questions of creators there, but don't be offended if they are more interested in building diff -c -r --new-file ds2.0r26/lib/doc/faq/admin ds2.0r29/lib/doc/faq/admin *** ds2.0r26/lib/doc/faq/admin Sat Mar 11 11:22:47 2006 --- ds2.0r29/lib/doc/faq/admin Wed Jul 5 00:01:03 2006 *************** *** 420,426 **** %^GREEN%^*** I found a bug. For real. Can you please fix it?***%^RESET%^ ! Email me: @users.sourceforge.net Please include a detailed description of the bug, and the exact error text and commands that produced it. A log file or --- 420,426 ---- %^GREEN%^*** I found a bug. For real. Can you please fix it?***%^RESET%^ ! Email me: @comcast.net Please include a detailed description of the bug, and the exact error text and commands that produced it. A log file or diff -c -r --new-file ds2.0r26/lib/doc/faq/general ds2.0r29/lib/doc/faq/general *** ds2.0r26/lib/doc/faq/general Sat Mar 11 11:22:47 2006 --- ds2.0r29/lib/doc/faq/general Wed Jul 5 00:01:03 2006 *************** *** 159,165 **** %^GREEN%^ How do I get started? %^RESET%^ ! Download the latest version from http://dead-souls.sourceforge.net/ or http://www.mudmagic.com/codes/download/lpc/mudos/dead_souls and install it. There are versions available for Windows and for Unix. The main difference between the two is the driver. The Windows driver is a Windows --- 159,165 ---- %^GREEN%^ How do I get started? %^RESET%^ ! Download the latest version from http://dead-souls.net/ or http://www.mudmagic.com/codes/download/lpc/mudos/dead_souls and install it. There are versions available for Windows and for Unix. The main difference between the two is the driver. The Windows driver is a Windows diff -c -r --new-file ds2.0r26/lib/doc/guide/chapter05 ds2.0r29/lib/doc/guide/chapter05 *** ds2.0r26/lib/doc/guide/chapter05 Sun Jun 18 16:20:51 2006 --- ds2.0r29/lib/doc/guide/chapter05 Wed Jul 5 00:01:03 2006 *************** *** 36,42 **** classes, Dead Souls provides you the ability to use the existing stock classes, and permits you to create your own. The files in /secure/cfg/classes describe them. ! See http://dead-souls.sourceforge.net/ds-creator-faq.html#2.46 for the exact syntax of these files. You'll notice that there is a field for "how important" --- 36,42 ---- classes, Dead Souls provides you the ability to use the existing stock classes, and permits you to create your own. The files in /secure/cfg/classes describe them. ! See http://dead-souls.net/ds-creator-faq.html#2.46 for the exact syntax of these files. You'll notice that there is a field for "how important" diff -c -r --new-file ds2.0r26/lib/doc/guide/chapter08 ds2.0r29/lib/doc/guide/chapter08 *** ds2.0r26/lib/doc/guide/chapter08 Sun Jun 18 16:20:52 2006 --- ds2.0r29/lib/doc/guide/chapter08 Wed Jul 5 00:01:03 2006 *************** *** 195,201 **** keep track of which fields have been plowed, how many times, and how long it'll take to get to harvest time. Dead Souls daemons typically use object ! persistence files ( http://dead-souls.sourceforge.net/ds-admin-faq.html#80 ) to avoid losing information during object reloads or mud reboots. A FARMING_D is exactly what you need to keep track of and manage this kind of data. --- 195,201 ---- keep track of which fields have been plowed, how many times, and how long it'll take to get to harvest time. Dead Souls daemons typically use object ! persistence files ( http://dead-souls.net/ds-admin-faq.html#80 ) to avoid losing information during object reloads or mud reboots. A FARMING_D is exactly what you need to keep track of and manage this kind of data. diff -c -r --new-file ds2.0r26/lib/doc/hbook/chapter04 ds2.0r29/lib/doc/hbook/chapter04 *** ds2.0r26/lib/doc/hbook/chapter04 Sat Mar 11 11:14:53 2006 --- ds2.0r29/lib/doc/hbook/chapter04 Wed Jul 5 00:01:03 2006 *************** *** 23,31 **** friends to tackle the orcs together, or raise your level to the point where you're tough enough to take them on. ! To raise your level, wander around in the newbie mansion. There's ! lots of loot there you can sell at Otik's shop, and with the cash you ! can then get some proper weaponry and armor. Silver is heavy, so don't try to carry all your money around all the time. Request an account from Zoe the banker and keep your money there until you really need it. --- 23,34 ---- friends to tackle the orcs together, or raise your level to the point where you're tough enough to take them on. ! To raise your level, wander around in the newbie mansion, which ! is south of the village church. ! ! There's lots of loot there you can sell at Otik's shop, and with the ! cash you can then get some proper weaponry and armor. ! Silver is heavy, so don't try to carry all your money around all the time. Request an account from Zoe the banker and keep your money there until you really need it. *************** *** 34,40 **** finding the secret room will give you experience and quest points too. (hint, there might be more than one secret room) ! Once you have enough experience and/and or points, go to Dirk in the adventurers hall and "%^GREEN%^ask dirk to advance%^RESET%^". Make sure you learn some spells from Herkimer, because if you --- 37,43 ---- finding the secret room will give you experience and quest points too. (hint, there might be more than one secret room) ! Once you have enough experience and/or points, go to Dirk in the adventurers hall and "%^GREEN%^ask dirk to advance%^RESET%^". Make sure you learn some spells from Herkimer, because if you diff -c -r --new-file ds2.0r26/lib/doc/help/creators/admin ds2.0r29/lib/doc/help/creators/admin *** ds2.0r26/lib/doc/help/creators/admin Fri May 12 21:13:22 2006 --- ds2.0r29/lib/doc/help/creators/admin Wed Jul 5 00:01:10 2006 *************** *** 10,18 **** Your most valuable tools will be the Dead Souls FAQs: ! http://dead-souls.sourceforge.net/ds-admin-faq.html ! http://dead-souls.sourceforge.net/ds-creator-faq.html Almost everything else will flow from your familiarity and understanding of the information there. --- 10,18 ---- Your most valuable tools will be the Dead Souls FAQs: ! http://dead-souls.net/ds-admin-faq.html ! http://dead-souls.net/ds-creator-faq.html Almost everything else will flow from your familiarity and understanding of the information there. diff -c -r --new-file ds2.0r26/lib/doc/help/creators/creation ds2.0r29/lib/doc/help/creators/creation *** ds2.0r26/lib/doc/help/creators/creation Mon Jan 23 09:17:12 2006 --- ds2.0r29/lib/doc/help/creators/creation Wed Jul 5 00:01:10 2006 *************** *** 16,21 **** In the meantime, take a look below at the commands in actual use, with a few added comments: ! http://dead-souls.sourceforge.net/example.html --- 16,21 ---- In the meantime, take a look below at the commands in actual use, with a few added comments: ! http://dead-souls.net/example.html diff -c -r --new-file ds2.0r26/lib/doc/help/creators/creator_general ds2.0r29/lib/doc/help/creators/creator_general *** ds2.0r26/lib/doc/help/creators/creator_general Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/doc/help/creators/creator_general Wed Jul 5 00:01:10 2006 *************** *** 0 **** --- 1,21 ---- + Common Creator commands: + + File commands: + ------------- + cp - copy a file + mv - move or rename a file + cd - change your working directory + ls - list the contents of your directory + ed - edit a file (WARNING: if you get stuck, type a + single period on a blank line, then Q, then enter) + rm - delete a file + more - page through the contents of a file + cat - display the entire contents of a file + update - load a file into memory + + Creation commands (used on objects, not files): + ------------- + create, modify, reload, delete, add, copy + + For more information on a command, type: help + See also: help help diff -c -r --new-file ds2.0r26/lib/doc/help/creators/plan ds2.0r29/lib/doc/help/creators/plan *** ds2.0r26/lib/doc/help/creators/plan Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/doc/help/creators/plan Fri Jul 7 19:41:41 2006 *************** *** 0 **** --- 1,7 ---- + Your plan file is the extra information others see when + they finger you, usually listing what your projects are + and what you've been up to. To modify your plan, + edit the .plan file in your home directory. For example, + + cd + ed .plan diff -c -r --new-file ds2.0r26/lib/doc/help/creators/profile ds2.0r29/lib/doc/help/creators/profile *** ds2.0r26/lib/doc/help/creators/profile Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/doc/help/creators/profile Fri Jul 7 19:41:41 2006 *************** *** 0 **** --- 1,11 ---- + Your profile is a file that contains a list of + instructions. When you log in, the mud will force + you to execute those commands. To modify what those + "startup commands" are, edit the .profile file in + your home directory. For example: + + cd + ed .profile + + Note that the mud cannot force you to do + certain things as a security measure. diff -c -r --new-file ds2.0r26/lib/doc/help/players/alias ds2.0r29/lib/doc/help/players/alias *** ds2.0r26/lib/doc/help/players/alias Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/doc/help/players/alias Wed Jul 5 00:01:10 2006 *************** *** 0 **** --- 1,28 ---- + Syntax: alias + alias $* + + This command lets you substitute a short command for a long one. + For example, rather than type out "get all from corpse" you + can create this alias: + + %^GREEN%^alias gc get all from corpse%^RESET%^ + + And all you need do is type "gc" to get the same effect. + You can also use a wildcard, like this: + + %^GREEN%^alias gc get all from $* corpse%^RESET%^ + + So that typing: %^GREEN%^gc first%^RESET%^ + Expands out to: %^GREEN%^get all from first corpse%^RESET%^ + + The wildcard is also helpful for channel aliases: + + %^GREEN%^alias ige intergossipemote $*%^RESET%^ + + To see your aliases, type: %^GREEN%^alias%^RESET%^ + + To remove an alias, type alias plus the alias, like so: + + %^GREEN%^alias gc%^RESET%^ + + diff -c -r --new-file ds2.0r26/lib/doc/help/players/channels ds2.0r29/lib/doc/help/players/channels *** ds2.0r26/lib/doc/help/players/channels Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/doc/help/players/channels Wed Jul 5 00:01:10 2006 *************** *** 0 **** --- 1,55 ---- + Channels are an out-of-character (OOC) means for users + to communicate with each other. You may hear the terms + "channel" and "line" used interchangeably. + + There are two main types of channels: local and intermud. + The default Dead Souls distribution uses these channels as + local: + + cre - only creators hear this + gossip - general offtopic stuff + newbie - everyone can hear this unless they turn it off + thief - channel for the thief class + fighter - channel for the fighter class + error - system errors + death - death announcements + mage - channel for the thief class + priest - channel for the thief class + explorer - channel for the thief class + admin - only admins hear this + + The following are intermud channels: + + ds - Dead Souls mud code talk + ds_test - testing testing 1, 2, 3, etc + intergossip - general offtopic stuff + lpuni - LPUniversity discussion + intercre - general technical chatter + + + By default, players do not have access to intermud channels. + Mud admins are asked to maintain some level of adherence to + the channel topics from their users. Muds that violate the + router admin's interpretation of "on-topic" will be asked + politely, if possible, to conform to the channel standards. + + Continued violations subject the offending mud to potential + banning. + + Hate speech is not tolerated, and flaming is frowned + upon, though each mud is expected to police itself and + enforce these standards on their own. + + If you don't like these rules, use a router other than the default. + + For local channels of course, none of this applies. Whatever + local rules are in place, that's what must be obeyed. + + Some tips: + --------- + To turn on/off a channel, type its name by itself, like this: newbie + + To know who is listening to a channel: list newbie + + To see a brief history of channel messages: hist newbie + diff -c -r --new-file ds2.0r26/lib/doc/help/players/player_general ds2.0r29/lib/doc/help/players/player_general *** ds2.0r26/lib/doc/help/players/player_general Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/doc/help/players/player_general Wed Jul 5 00:01:10 2006 *************** *** 0 **** --- 1,23 ---- + Basic player commands: + + look - get a view of your environment + inventory - take stock of your possessions + stat - your health and statistics + score - your overall ranking and information + + Dealing with objects: + -------------------- + look at, look in + get, drop, put, give + open, close + read + wield, unwield, wear, remove + + Moving around: + ------------- + n, s, e, w, ne, nw, se, sw, u, d + enter, go out, climb up, climb down, jump down + crawl, fly + + See also: help help + diff -c -r --new-file ds2.0r26/lib/domains/Ylsrim/room/bazaar.c ds2.0r29/lib/domains/Ylsrim/room/bazaar.c *** ds2.0r26/lib/domains/Ylsrim/room/bazaar.c Wed Dec 7 13:59:22 2005 --- ds2.0r29/lib/domains/Ylsrim/room/bazaar.c Wed Jul 5 00:01:11 2006 *************** *** 20,26 **** // the is the amount of light the street lamps make at night SetAmbientLight(30); // the obvious exits tell people how to leave the room - SetObviousExits("n, s, enter armory, enter weaponry"); // set the sounds people hear SetListen("Vendors are begging you to come look at their goods."); // set the short description... should not be capitalized --- 20,25 ---- diff -c -r --new-file ds2.0r26/lib/domains/Ylsrim/room/vote_hall.c ds2.0r29/lib/domains/Ylsrim/room/vote_hall.c *** ds2.0r26/lib/domains/Ylsrim/room/vote_hall.c Mon Nov 7 13:29:44 2005 --- ds2.0r29/lib/domains/Ylsrim/room/vote_hall.c Wed Jul 5 00:01:11 2006 *************** *** 20,28 **** SetProperties( ([ "no kill" : 1, "no attack" : 1, "no steal" : 1, "no magic" : 1, "light" : 3, "no bump" : 1, "no teleport" : 1 ]) ); SetShort("voting hall"); ! SetLong("You are in the voting hall of Dead Souls. This is where " ! "people come to nominate candidates for class leader and to " ! "cast their vote. There is a list posted on the wall here."); SetItems( ([ "list" : "This is the list of candidates." ]) ); SetRead( "list", (: ReadList :) ); SetObviousExits("d"); --- 20,26 ---- SetProperties( ([ "no kill" : 1, "no attack" : 1, "no steal" : 1, "no magic" : 1, "light" : 3, "no bump" : 1, "no teleport" : 1 ]) ); SetShort("voting hall"); ! SetLong("You are in the voting hall of Ylsrim. This is where people come to nominate candidates for class leader and to cast their vote. There is a list posted on the wall here."); SetItems( ([ "list" : "This is the list of candidates." ]) ); SetRead( "list", (: ReadList :) ); SetObviousExits("d"); diff -c -r --new-file ds2.0r26/lib/domains/campus/armor/foodsmock.c ds2.0r29/lib/domains/campus/armor/foodsmock.c *** ds2.0r26/lib/domains/campus/armor/foodsmock.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/armor/foodsmock.c Sun Jul 9 22:06:36 2006 *************** *** 6,12 **** static void create(){ armor::create(); SetKeyName("uniform"); ! SetAdjectives( ({"food workers"}) ); SetId( ({"overalls", "smock"}) ); SetShort("a food worker's uniform"); SetLong("This is a set of overalls used by food workers to keep their bodies and the food at a healthy distance."); --- 6,12 ---- static void create(){ armor::create(); SetKeyName("uniform"); ! SetAdjectives( ({"food workers","food worker's"}) ); SetId( ({"overalls", "smock"}) ); SetShort("a food worker's uniform"); SetLong("This is a set of overalls used by food workers to keep their bodies and the food at a healthy distance."); diff -c -r --new-file ds2.0r26/lib/domains/campus/armor/wizard_hat.c ds2.0r29/lib/domains/campus/armor/wizard_hat.c *** ds2.0r26/lib/domains/campus/armor/wizard_hat.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/armor/wizard_hat.c Sun Jul 9 22:06:36 2006 *************** *** 2,21 **** #include #include inherit LIB_ARMOR; static void create(){ armor::create(); ! SetKeyName("wizard hat"); ! SetId(({"hat","headgear"})); ! SetAdjectives(({"wizard","wizard's"})); SetShort("a wizard's hat"); SetLong("This is a large, floppy hat with a wide brim all "+ "around it, and a conical center. It is dark blue in color, "+ "and is decorated with pictures of yellow moons and stars."); SetMass(50); ! SetDollarCost(500); SetDamagePoints(100); SetArmorType(A_HELMET); SetProtection(BLUNT, 20); SetProtection(BLADE, 20); SetProtection(KNIFE, 20); } --- 2,28 ---- #include #include inherit LIB_ARMOR; + static void create(){ armor::create(); ! SetKeyName("wizard's hat"); ! SetAdjectives( ({"wizard","wizards", "floppy", "large", "conical", "blue"}) ); ! SetId( ({"hat"}) ); SetShort("a wizard's hat"); SetLong("This is a large, floppy hat with a wide brim all "+ "around it, and a conical center. It is dark blue in color, "+ "and is decorated with pictures of yellow moons and stars."); + SetProperties(([ + "beta" : 2, + ])); SetMass(50); ! SetBaseCost("silver",500); SetDamagePoints(100); SetArmorType(A_HELMET); SetProtection(BLUNT, 20); SetProtection(BLADE, 20); SetProtection(KNIFE, 20); } + void init(){ + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/campus/meals/red_wine.c ds2.0r29/lib/domains/campus/meals/red_wine.c *** ds2.0r26/lib/domains/campus/meals/red_wine.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/meals/red_wine.c Wed Dec 31 19:00:00 1969 *************** *** 1,22 **** - #include - #include - - inherit LIB_MEAL; - - static void create() { - meal::create(); - SetKeyName("red wine"); - SetId( ({"wine"}) ); - SetShort("a bottle of milk"); - SetLong("A fairly small bottle of milk from some unknown creature. It has " - "a greyish tint to it. It would take several of these bottles to quench " - "that deep down bodily thirst."); - SetMass(3); - SetMealType(MEAL_DRINK); - SetStrength(10); - SetMealMessages("You gulp down the bottle of milk.", "$N gulps down a small " - "bottle of milk."); - SetEmptyName("bottle"); - SetEmptyShort("an empty bottle"); - SetEmptyLong("A small bottle which used to contain a portion of milk."); - } --- 0 ---- diff -c -r --new-file ds2.0r26/lib/domains/campus/meals/wing.c ds2.0r29/lib/domains/campus/meals/wing.c *** ds2.0r26/lib/domains/campus/meals/wing.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/meals/wing.c Wed Dec 31 19:00:00 1969 *************** *** 1,29 **** - /* /domains/Praxis/etc/ale.c - * from Nightmare LPMud - * created by Descartes of Borg 950603 - */ - - #include - #include - - inherit LIB_MEAL; - - static void create() { - meal::create(); - SetKeyName("ale"); - SetId( ({ "bottle", "ale", "praxis ale" }) ); - SetShort("a bottle of ale"); - SetLong("A nice bottle of Lars' famous Praxis Ale."); - SetMass(60); - SetMealType(MEAL_FOOD); - SetMealMessages("You eat a chicken wing. Mmm!", - "$N enjoys a chicken wing. It looks delicious."); - } - void eventEat(){ - this_object()->goopy(); - return; - } - int goopy(){ - tell_room(environment(this_player()),"Gppy!\n"); - return 1; - } --- 0 ---- diff -c -r --new-file ds2.0r26/lib/domains/campus/npc/hans.c ds2.0r29/lib/domains/campus/npc/hans.c *** ds2.0r26/lib/domains/campus/npc/hans.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/npc/hans.c Wed Jul 5 19:58:19 2006 *************** *** 51,57 **** SetShort("Hans"); SetLong("Hans is a foreign exchange student from Germany."); SetLevel(5); - SetUnique(1); SetRace("human"); SetGender("male"); SetNoClean(1); --- 51,56 ---- diff -c -r --new-file ds2.0r26/lib/domains/campus/npc/rat.c ds2.0r29/lib/domains/campus/npc/rat.c *** ds2.0r26/lib/domains/campus/npc/rat.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/npc/rat.c Wed Jul 5 19:58:19 2006 *************** *** 1,9 **** - #include inherit LIB_SENTIENT; - static void create() { sentient::create(); SetKeyName("a mangy little rat"); --- 1,7 ---- *************** *** 12,18 **** SetLong("A scruffy little dirty rat."); SetLevel(1); SetMaxHealthPoints(5); - SetUnique(1); SetRace("rodent"); SetGender("male"); SetWanderSpeed(1); --- 10,15 ---- diff -c -r --new-file ds2.0r26/lib/domains/campus/obj/podium.c ds2.0r29/lib/domains/campus/obj/podium.c *** ds2.0r26/lib/domains/campus/obj/podium.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/obj/podium.c Wed Jul 5 00:01:11 2006 *************** *** 1,225 **** ! /* It works now, no define needed. ! * make sure someone does "setmc" or it won't do much. ! * setmc can only be done once, first come, first get i guess ;) ! * by Boy@frontiers. ! * Major corrections and modifications by Crat 25jul05 ! */ ! #include ! #include ! inherit LIB_STORAGE; ! string speaker; ! string mc; ! int x; ! object ob; ! static void create() { ! storage::create(); ! SetShort("a podium"); ! SetLong("This is the speaker's podium. It is about four feet tall "+ ! "and made of some expensive-looking, deep grain wood. This podium "+ ! "facilitates the running of meetings by giving the speaker the power "+ ! "to recognize individual people to speak at a time. There is "+ ! "some space in the podium to store things in, perhaps there is something "+ ! "in there now. For more "+ ! "details on running a meeting with the podium, type: help podium."); ! SetMass(10); ! SetId( ({"podium", "speaker's podium", "podium.c"}) ); ! SetDollarCost(-110); ! SetKeyName("podium"); ! SetId(({"podium","handler"})); ! SetAdjectives(({"wood","wooden","meeting","speaker's","Speaker's"})); ! SetDamagePoints(1000); ! SetPreventGet("You can't get that."); ! SetMaxCarry(20); ! SetInventory(([ ! "/domains/campus/obj/key1" : 1 ! ])); ! mc = ""; ! x = 0; ! speaker = ""; ! } ! void init() { ! ::init(); ! add_action("CatchInput", "",1); ! //add_action("eventSay", "say",1); ! //add_action("eventRaise", "raise"); ! //add_action("eventCallOn", "recognize"); ! //add_action("shaddap", "yell"); ! //add_action("shaddap", "shout"); ! //add_action("shaddap", "emote"); ! //add_action("help", "help"); ! //add_action("quiet", "quiet"); ! //add_action("changemc", "changemc"); ! //add_action("SetMc", "setmc"); ! ! } ! mixed CanGet(object ob) { return "The podium does not budge.";} ! ! ! ! int eventSay(string args) { ! if (mc == this_player()->GetKeyName()) { ! this_player()->eventPrint("You say \"%^CYAN%^" + args + "\""); ! say(this_player()->GetName() + " says \"%^CYAN%^" + args + "\""); ! return 1; ! } ! ! if ( mc != "" && this_player()-> GetKeyName() != speaker) { ! this_player()->eventPrint("%^RED%^It is not polite to talk out of order."); ! this_player()->eventPrint("Raise your hand if you'd like to speak."); ! return 1; ! } ! ! } ! ! int eventCallOn(string args) { ! if (present((object)args)) { ! if (mc == this_player()->GetKeyName()) { ! speaker = args; ! write("You have called on " + speaker+".\n"); ! find_living(args)->eventPrint("%^CYAN%^" + capitalize(mc) + " has called on you, you may speak."); ! return 1; ! } ! else { ! this_player()->eventPrint("Only the speaker can do that."); ! return 1; ! } ! } ! else { ! write("%^CYAN%^This person is not here to be called on."); ! return 1; ! } ! } ! int eventRaise() { ! string dude; ! dude=this_player()->GetKeyName(); ! if(dude != mc && dude != speaker) { ! tell_room(environment(this_player()), ! this_player()->GetName()+" raises "+ ! possessive(this_player())+ ! " hand.", ({this_player()}) ); ! this_player()->eventPrint("%^CYAN%^You raise your hand."); ! return 1; ! } ! else { ! write("You can speak already. Say what's on your mind."); ! return 1; ! } ! } ! int shaddap() { ! if(mc != "" && this_player()->GetKeyName() != speaker){ ! write("%^RED%^It would be impolite to do that at this time."); ! return 1; ! } ! } ! int help(string args) { ! if (args != "podium") { ! return 0; ! } ! else { ! write("%^GREEN%^This is the speakers podium, it is where the " ! "speaker stands during a speech. This podium " ! "has special properties, it can prevent others " ! "from speaking out of turn, if you are the "+ ! "speaker.%^RESET%^"); ! if (this_player()->GetKeyName() == mc) { ! write("%^RED%^Available commands:"); ! write("%^YELLOW%^recognize %^RESET%^: Calls on another to speak."); ! write("%^YELLOW%^say %^RESET%^: As the speaker, you can say things whenever you like."); ! write("%^YELLOW%^quiet %^RESET%^: Revokes the speaking privilege to the person you last called on."); ! write("%^YELLOW%^changemc %^RESET%^: Removes yourself as mc, and let someone else take over."); ! return 1; ! } ! else { ! write("%^RED%^Available commands:"); ! write("%^YELLOW%^raise %^RESET%^: Raise your hand, to motion to the speaker that you would like to speak."); ! write("%^YELLOW%^say %^RESET%^ : Say something, you only may do this if the speaker has called on you."); ! if (x == 0) { ! write("%^YELLOW%^setmc%^RESET%^ : There is no mc currently, use this command to set one."); ! } ! return 1; ! } ! } ! } ! int quiet() { ! write("%^CYAN%^You thank " + capitalize(speaker) + " for speaking."); ! find_living(speaker)->eventPrint("%^CYAN%^" + capitalize(mc) + " thanks you for you speaking."); ! speaker = mc; ! return 1; ! } ! int changemc(string args) { ! if (args != 0) { ! if (this_player()->GetKeyName() != mc) { ! write("%^RED%^You are not the mc to begin with, you cannot give that position away."); ! return 1; ! } ! else { ! if (!present(args)) { ! write("%^CYAN%^" + args + " is not present, and therefore cannot be mc."); ! return 1; ! } ! else { ! write("%^CYAN%^You hand the podium over to " + args); ! mc = args; ! say("%^CYAN%^" + capitalize(args) + " is the new head speaker."); ! find_living(mc)->eventPrint("%^BLUE%^You are the new head speaker!"); ! find_living(mc)->eventPrint("The command \"help podium\" can help you, if you don't know what to do."); ! return 1; ! } ! } ! } ! else { ! write("%^CYAN%^Syntax:"); ! write("changemc "); ! return 1; ! } ! } ! int SetMc(string args) { ! if (x==0) { ! if (args != 0) { ! if (present(args)) { ! mc = args; ! say("%^CYAN%^" + capitalize(mc) + " is the speaker."); ! write("You set " + capitalize(args) + " as the speaker."); ! x++; ! return 1; ! } ! else { ! write("You cannot set him/her as the speaker, he/she is not here!"); ! return 1; ! } ! } ! else { ! write("%^CYAN%^Syntax:"); ! write("setmc "); ! return 1; ! } ! } ! else { ! write("There is already a speaker, you cannot set another one."); ! return 1; ! } ! } ! ! void CatchInput(string str){ ! string cmd,args; ! string *cmds; ! cmds = ({ "setmc","say","help","quiet","changemc","recognize" }); ! cmd=query_verb(); ! write("cmd: "+cmd); ! if(str && str!= "") args = str; ! write("args: "+args); ! if(cmd == "emote" || member_array(cmd, "/daemon/soul"->GetEmotes()) != -1){ ! shaddap(); ! return; ! } ! //if(cmd == "setmc") SetMc(args); ! //if(cmd == "say") eventSay(args); ! //if(cmd == "help") help(args); ! //if(cmd == "quiet") quiet(); ! //if(cmd == "changemc") changemc(args); ! //if(cmd == "recognize") eventCallOn(args); ! //if(cmd == "raise") eventRaise(); ! //if(member_array(cmd,cmds) != -1) return; ! //if(cmd == "say") return; ! } ! --- 1,713 ---- ! /* It works now, no define needed. ! * make sure someone does "setmc" or it won't do much. ! * setmc can only be done once, first come, first get i guess ;) ! * by Boy@frontiers. ! * Major corrections and modifications by Crat 25jul05 ! */ ! #include ! #include ! inherit LIB_STORAGE; ! ! #define DEFAULT_BOUNCE_ROOM "/domains/town/room/adv_guild" ! string bounce_room ; /* File name of the bounce room */ ! string *voters ; /* Array of names of users who have voted */ ! string *agenda ; /* Array of agenda item strings. */ ! mapping votes ; /* Keys are names, data are votes cast */ ! string vote_str ; /* The proposition being voted on */ ! int endtime ; /* Time at which the speaker/vote ends */ ! int votelog ; /* 1 if votes are being announced, else 0 */ ! ! string speaker; ! string mc; ! int x; ! object ob; ! static void create() { ! storage::create(); ! SetShort("a podium"); ! SetLong("This is the speaker's podium. It is about four feet tall "+ ! "and made of some expensive-looking, deep grain wood. This podium "+ ! "facilitates the running of meetings by giving the speaker the power "+ ! "to recognize individual people to speak at a time. There is "+ ! "some space in the podium to store things in, perhaps there is something "+ ! "in there now. For more "+ ! "details on running a meeting with the podium, type: help podium."); ! SetMass(10); ! SetId( ({"podium", "speaker's podium", "podium.c"}) ); ! SetDollarCost(-110); ! SetKeyName("podium"); ! SetId(({"podium","handler"})); ! SetAdjectives(({"wood","wooden","meeting","speaker's","Speaker's"})); ! SetDamagePoints(1000); ! SetPreventGet("You can't get that."); ! SetMaxCarry(20); ! ! SetInventory(([ ! ])); ! ! mc = ""; ! x = 0; ! speaker = ""; ! ! vote_str = "none" ; ! voters = ({ }) ; ! votes = ([ ]) ; ! agenda = ({ }) ; ! bounce_room = DEFAULT_BOUNCE_ROOM ; ! ! } ! void init() { ! ::init(); ! add_action("eventSay", "say",1); ! add_action("eventRaise", "raise"); ! add_action("eventCallOn", "recognize"); ! add_action("shaddap", "yell"); ! add_action("shaddap", "shout"); ! add_action("shaddap", "emote"); ! add_action("help", "help"); ! add_action("quiet", "quiet"); ! add_action("changemc", "changemc"); ! add_action("SetMc", "setmc"); ! add_action ("echo", "echo") ; ! add_action ("vote", "vote") ; ! add_action ("call_for_vote", "call") ; ! add_action ("call_for_roll", "rollcall") ; ! add_action ("permit_entry", "permit") ; ! add_action ("localtime", "time") ; ! add_action ("reset_clock", "reset") ; ! add_action ("show_agenda", "agenda") ; ! add_action ("add_items", "add") ; ! add_action ("remove_item", "remove") ; ! add_action ("clear_items", "clear") ; ! add_action ("eject_player", "eject") ; ! add_action ("privacy", "privacy"); ! add_action ("privacy", "priv"); ! add_action ("localupdate", "update") ; ! add_action ("step_down", "step" ); ! } ! mixed CanGet(object ob) { return "The podium does not budge.";} ! ! ! ! int eventSay(string args) { ! string foo; ! ! if (mc == this_player()->GetKeyName()) { ! this_player()->eventPrint("You say %^CYAN%^\"" + capitalize(args) + "\""); ! say(this_player()->GetName() + " says %^CYAN%^\"" + capitalize(args) + "\""); ! return 1; ! } ! if ( mc != "" && this_player()-> GetKeyName() != speaker ) { ! this_player()->eventPrint("%^RED%^It is not polite to talk out of order."); ! this_player()->eventPrint("Raise your hand if you'd like to speak."); ! return 1; ! } ! if ((!args) || (args == " ")) { ! write ("You mutter to yourself.\n") ; ! return 1 ; ! } ! foo = wrap((string)this_player()->GetCapName() + ! " says: %^CYAN%^\"" + capitalize(args)) ; ! say (foo) ; ! write(wrap("You say: %^CYAN%^\"" + capitalize(args))); ! return 1; ! ! } ! ! ! int eventCallOn(string args) { ! if (present((object)args)) { ! if (mc == this_player()->GetKeyName()) { ! speaker = args; ! write("You have called on " + speaker+".\n"); ! find_living(args)->eventPrint("%^CYAN%^" + capitalize(mc) + " has called on you, you may speak."); ! return 1; ! } ! else { ! this_player()->eventPrint("Only the speaker can do that."); ! return 1; ! } ! } ! else { ! write("%^CYAN%^This person is not here to be called on."); ! return 1; ! } ! } ! ! ! int eventRaise() { ! string dude; ! dude=this_player()->GetKeyName(); ! if(dude != mc && dude != speaker) { ! tell_room(environment(this_player()), ! this_player()->GetName()+" raises "+ ! possessive(this_player())+ ! " hand.", ({this_player()}) ); ! this_player()->eventPrint("%^CYAN%^You raise your hand."); ! return 1; ! } ! else { ! write("You can speak already. Say what's on your mind."); ! return 1; ! } ! } ! ! ! int shaddap() { ! if(mc != "" && this_player()->GetKeyName() != speaker){ ! write("%^RED%^It would be impolite to do that at this time."); ! return 1; ! } ! } ! ! ! int help(string args) { ! if (args != "podium") { ! return 0; ! } ! else { ! write("%^GREEN%^This is the speakers podium, it is where the " ! "speaker stands during a speech. This podium " ! "has special properties, it can prevent others " ! "from speaking out of turn, if you are the "+ ! "speaker.%^RESET%^"); ! if (this_player()->GetKeyName() == mc) { ! write("%^RED%^Available commands:"); ! write("%^YELLOW%^recognize %^RESET%^: Calls on another to speak."); ! write("%^YELLOW%^say %^RESET%^: As the speaker, you can say things whenever you like."); ! write("%^YELLOW%^quiet %^RESET%^: Revokes the speaking privilege to the person you last called on."); ! write("%^YELLOW%^changemc %^RESET%^: Removes yourself as mc, and let someone else take over."); ! write("%^YELLOW%^add %^RESET%^: Add agenda item to the bottom of the agenda."); ! write("%^YELLOW%^remove %^RESET%^: Remove agenda item from the agenda."); ! write("%^YELLOW%^clear agenda%^RESET%^: Clear the agenda."); ! write("%^YELLOW%^permit %^RESET%^: Permit player to enter the meeting room when locked."); ! write("%^YELLOW%^eject %^RESET%^: Eject player from the meeting room."); ! write("%^YELLOW%^time [minutes/seconds]%^RESET%^: Set the clock to minutes or seconds."); ! write("%^YELLOW%^reset clock%^RESET%^: Clear the clock."); ! write("%^YELLOW%^step down%^RESET%^: Step down as head speaker."); ! write("%^YELLOW%^rollcall [minutes/seconds] %^RESET%^: Call for a roll call vote,\n" ! "\tlasting num minutes or seconds, on ."); ! write("%^YELLOW%^add after %^RESET%^: Add agenda item after agenda item #.\n" ! "\tadd after 0 adds to the top of the list."); ! write("%^YELLOW%^call [minutes/seconds] %^RESET%^: Call for a vote, lasting num minutes\n" ! "\tor seconds, on ."); ! return 1; ! } ! else { ! write("%^RED%^Available commands:"); ! write("%^YELLOW%^raise %^RESET%^: Raise your hand, to motion to the speaker that you would like to speak."); ! write("%^YELLOW%^say %^RESET%^ : Say something, you only may do this if the speaker has called on you."); ! if (x == 0) { ! write("%^YELLOW%^setmc%^RESET%^ : There is no mc currently, use this command to set one."); ! } ! return 1; ! } ! } ! } ! ! ! int quiet() { ! if (mc == this_player()->GetKeyName()) { ! write("%^CYAN%^You thank " + capitalize(speaker) + " for speaking."); ! find_living(speaker)->eventPrint("%^CYAN%^" + capitalize(mc) + " thanks you for you speaking."); ! speaker = mc; ! return 1; ! } ! write ("Only the mc may use this command.\n") ; ! return 1; ! } ! ! ! int changemc(string args) { ! if (args != 0) { ! if ( this_player()->GetKeyName() != mc ) { ! write("%^RED%^You are not the mc to begin with, you cannot give that position away."); ! return 1; ! } ! else { ! if (!present(args)) { ! write("%^CYAN%^" + args + " is not present, and therefore cannot be mc."); ! return 1; ! } ! else { ! write("%^CYAN%^You hand the podium over to " + args); ! mc = args; ! say("%^CYAN%^" + capitalize(args) + " is the new head speaker."); ! find_living(mc)->eventPrint("%^BLUE%^You are the new head speaker!"); ! find_living(mc)->eventPrint("The command \"help podium\" can help you, if you don't know what to do."); ! return 1; ! } ! } ! } ! else { ! write("%^CYAN%^Syntax:"); ! write("changemc "); ! return 1; ! } ! } ! ! int step_down(string args){ ! if (args == "down") { ! if ( this_player()->GetKeyName() != mc ) { ! write("%^RED%^You are not the mc to begin with, you cannot give that position away."); ! return 1; ! } ! say("%^CYAN%^" + capitalize(mc) + " has stepped down as the head speaker."); ! write ( "You step down as the head speaker" ); ! mc = ""; ! x--; ! load_object(base_name(environment(this_object())))->AutoDeactivate(); ! return 1; ! } ! else { ! write("%^CYAN%^Syntax:"); ! write(""); ! return 1; ! } ! ! } ! ! int SetMc(string args) { ! if (x==0) { ! if (args != 0) { ! if (present(args) ) { ! mc = args; ! say("%^CYAN%^" + capitalize(mc) + " is the speaker."); ! write("You set " + capitalize(args) + " as the speaker."); ! find_living(mc)->eventPrint("The command \"help podium\" can help you, if you don't know what to do."); ! x++; ! return 1; ! } ! else { ! write("You cannot set him/her as the speaker, he/she is not here!"); ! return 1; ! } ! } ! else { ! write("%^CYAN%^Syntax:"); ! write("setmc "); ! return 1; ! } ! } ! else { ! write("There is already a speaker, you cannot set another one."); ! return 1; ! } ! } ! ! int privacy(string str){ ! ! if ( mc != this_player()->GetKeyName() ) { ! write ("Only the mc may use the shield.\n") ; ! return 1 ; ! } ! if(str=="on" || str == "1"){ ! load_object(base_name(environment(this_object())))->set_privacy( 1 ); ! write("You enable the privacy shield.\n"); ! say(this_player()->GetName()+" enables a privacy force field around the room."); ! return 1; ! } ! if(str=="off" || str == "0"){ ! load_object(base_name(environment(this_object())))->AutoDeactivate(); ! write("You disable the privacy shield.\n"); ! say(this_player()->GetName()+" disables a privacy force field around the room."); ! return 1; ! } ! } ! ! // Echoing is always forbidden. It's just too much of a hassle. ! int echo (string str) { ! write ("Echoing is forbidden in the conference room at all times.\n") ; ! return 1 ; ! } ! ! // Permit_entry lets the mc bring someone into the conference room ! // when it is locked. ! int permit_entry (string name) { ! ! object user ; ! int oldlock ; ! ! if ( mc != this_player()->GetKeyName() ) { ! write ("Only the mc may permit entry into a locked conference.\n") ; ! return 1 ; ! } ! user = find_player(name) ; ! if (!user) { ! write ("There is no user by that name.\n") ; ! return 1 ; ! } ! if (present(user,environment(this_object()))) { ! write (capitalize(name)+" is already here!\n") ; ! return 1 ; ! } ! // We save the old locked status of the room, and restore it when we're ! // done. You can "permit" entry into an unlocked conference if you want ! // to: it saves the person the trouble of walking. ! oldlock = load_object(base_name(environment(this_object())))->get_privacy() ; ! load_object(base_name(environment(this_object())))->set_privacy( 0 ); ! user -> eventMove(environment(this_object())) ; ! load_object(base_name(environment(this_object())))->set_privacy( oldlock ); ! write ("You bring "+capitalize(name)+" into the conference.\n") ; ! tell_object (user, capitalize(mc)+" permits you to enter.\n") ; ! say (capitalize(name)+" has been permitted to enter the conference.\n", user) ; ! return 1 ; ! } ! ! ! ! // Eject_player lets the mc banish a player from the room and dump ! // him in the bounce room. Not very effective if the room is unlocked, ! // except perhaps as a warning. ! int eject_player (string str) { ! ! object ob ; ! ! if ( mc != this_player()->GetKeyName() ) { ! write ("Only the mc may eject players.\n") ; ! return 1 ; ! } ! ob = find_player(str) ; ! if (!ob || !present (ob, environment(this_object()))) { ! write ("There is no player named "+capitalize(str)+" here.\n") ; ! return 1 ; ! } ! write ("You eject "+capitalize(str)+" from the room!\n") ; ! tell_object (ob, "You have been ejected from the room.\n") ; ! say (capitalize(str)+" has been ejected from the room.\n") ; ! ob->eventMove(bounce_room) ; ! return 1 ; ! } ! ! // Localtime shows the user the amount of time left on the room clock. ! // The name is chosen to avoid colliding with the time() efun. ! // The mc may also use this function to set the time on the clock ! // and start it running. See the help documents for more information on ! // how the clock works. ! varargs int localtime (string str) { ! ! int i, min, sec ; ! string foo ; ! ! // If no string, then we just indicate how much time is left on the clock. ! if (!str) { ! if (!endtime || endtime == 0) { ! write ("Time is not running at the moment.\n") ; ! return 1 ; ! } ! i = time() ; ! i = endtime - i ; ! min = (i/60) ; ! sec = i - (min*60) ; ! if (min==1) { ! write ("The clock shows 1 minute and "+sec+" seconds remaining.\n") ; ! } else { ! write ("The clock shows "+min+" minutes and "+sec+" seconds remaining.\n") ; ! } ! return 1 ; ! } ! // If there is a string, then the user is trying to set the clock to some ! // number of minutes or seconds. ! if ( mc != this_player()->GetKeyName() ) { ! write ("Only the mc may set the clock.\n") ; ! return 1 ; ! } ! // You cannot set a new time if the clock is running. This is for safety. ! // You must reset the clock first. See below. ! if (endtime!=0) { ! write ("The clock is running. You must reset the clock first.\n" ! ) ; ! return 1 ; ! } ! if (sscanf(str, "%d min%s", i, foo) == 2) { ! i=i*60 ; ! } else { ! if (sscanf(str, "%d seconds", i) != 1) { ! write ("You must set a number of minutes or seconds: ie, 3 minutes or 90 seconds.\n") ; ! return 1 ; ! } ! } ! write ("You set the clock to "+str+".\n") ; ! say (capitalize(mc)+" sets the clock to "+str+".\n") ; ! endtime = time()+i ; ! // We call_out to a function that prints a message when time runs out. ! call_out ("expire_time", i) ; ! return 1 ; ! } ! ! // Reset_clock lets the mc clear the clock before setting a new time ! // on it. ! int reset_clock (string str) { ! if (!str || str!="clock") { ! notify_fail ("Reset what?\n") ; ! return 0 ; ! } ! if ( mc != this_player()->GetKeyName() ) { ! write ("Only the mc may reset the clock.\n") ; ! return 1 ; ! } ! if (endtime==0) { ! write ("The clock isn't running.\n") ; ! return 1 ; ! } ! endtime = 0 ; ! write ("You clear the clock.\n") ; ! say (capitalize(mc)+" clears the clock.\n") ; ! // Clear any pending call_outs that may be left behind. ! remove_call_out("expire_time") ; ! remove_call_out("expire_vote") ; ! return 1 ; ! } ! ! // Expire_time lets the conference room know that time has expired. It ! // doesn't force the speaker to shut up or anything like that: that's left ! // to the mcs discretion. ! int expire_time() { ! tell_room (environment(this_object()),"The clock runs out.\n") ; ! endtime = 0 ; ! } ! ! ! // Show_agenda lets users see the current agenda. ! int show_agenda() { ! ! int i ; ! ! if (!agenda || sizeof(agenda)==0) { ! write ("The agenda has not been set.\n") ; ! return 1 ; ! } ! write ("The current agenda is:\n") ; ! for (i=0;iGetKeyName() ) { ! write ("Only the mc may clear the agenda.\n") ; ! return 1 ; ! } ! if (!str || str!="agenda") { ! write ("Usage: clear [agenda]\n") ; ! return 1 ; ! } ! agenda = ({ }) ; ! write ("The agenda has been cleared.\n") ; ! say ("The agenda has been cleared.\n") ; ! return 1 ; ! } ! ! // Add_agenda_item lets the mc add an agenda item. If the argument ! // is of the form "after ", then string is added to the ! // agenda AFTER item int. Agenda items are numbered 1-N rather than 0-(N-1). ! int add_items (string str) { ! ! int post ; ! string prop ; ! ! if ( mc != this_player()->GetKeyName() ) { ! notify_fail ("Only the mc may add agenda items.\n") ; ! return 0 ; ! } ! if (!str) { ! write ("Usage: add item or add after N item\n") ; ! return 1 ; ! } ! if (sscanf(str,"after %d %s", post, prop)!=2) { ! agenda += ({ str }) ; ! write ("Added the following item to the agenda\n"+str+"\n") ; ! return 1 ; ! } ! if (post<0 || post>=sizeof(agenda)) { ! notify_fail ("Item number out of range.\n") ; ! return 0 ; ! } ! if (post==0) agenda = ({ prop }) + agenda ; else ! agenda = agenda[0..post-1] + ({ prop }) + agenda[post..sizeof(agenda)] ; ! write ("Added the following agenda item after item "+post+":\n"+ ! prop+"\n") ; ! return 1 ; ! } ! ! // Remove_item lets the mc take an item off the agenda. ! int remove_item (string str) { ! ! int agitem ; ! ! if (!str) { ! notify_fail ("Usage: remove \n") ; ! return 0 ; ! } ! if (sscanf(str,"%d",agitem)!=1) { ! notify_fail ("Usage: remove \n") ; ! return 0 ; ! } ! if (agitem<0 || agitem>sizeof(agenda)) { ! write ("Item number out of range.\n") ; ! return 0 ; ! } ! // Convert to 0-(N-1) numbering. ! agitem = agitem-1 ; ! write (agitem+"\n") ; ! write ("Removing the following agenda item:\n"+agenda[agitem]+"\n") ; ! if (agitem==0) { ! agenda = agenda[1..sizeof(agenda)-1] ; ! } else { ! if (agitem == sizeof(agenda)-1) { ! agenda = agenda[0..sizeof(agenda)-2] ; ! } else { ! agenda = agenda[0..agitem-1] + agenda[agitem+1..sizeof(agenda)-1] ; ! } ! } ! return 1 ; ! } ! ! // Vote lets a player cast a vote on the proposed issue. See the help ! // document for details on how voting works. ! int vote (string str) { ! // With no argument, we print the proposal, if there is one. ! if (!str) { ! if (!vote_str || vote_str=="none") { ! write ("No vote is in progress.\n") ; ! return 1 ; ! } ! write ("Voting on: "+vote_str+"\n") ; ! return 1 ; ! } ! // If there is a argument, we interpret that string as a vote cast. ! if (!vote_str || vote_str=="none") { ! write ("No vote is in progress at this time.\n") ; ! return 1 ; ! } ! if (str!="yes" && str!="no" && str!="abstain") { ! write ("Please vote yes, no, or abstain..\n") ; ! return 1 ; ! } ! if (member_array( this_player()->GetName(),voters)!=-1) { ! write ("You have already voted!\n") ; ! return 1 ; ! } ! voters += ({ this_player()->GetName() }) ; ! votes[str] = votes[str]+1 ; ! write ("You vote "+str+" on "+vote_str+".\n") ; ! // If this is a roll call vote - ie, the votes are being logged - we announce ! // the vote to the log file and to the room. ! if (votelog) { ! say (capitalize(this_player()->GetName())+" votes "+capitalize(str)+".\n") ; ! } ! return 1 ; ! } ! ! // Call_for_vote allows the mc to call for a secret-ballot vote on ! // a proposal. ! int call_for_vote (string str) { ! ! string timestr, subjstr ; ! int i ; ! ! if ( mc != this_player()->GetKeyName() ) { ! write ("Only the mc may call for votes.\n") ; ! return 1 ; ! } ! // Must specify an amount of time for which votes may be cast, and a subject ! // which people are voting on. ! if (!str) { ! write ("Usage: call \n") ; ! return 1 ; ! } ! if (sscanf(str,"%d %s %s",i,timestr,subjstr)!=3) { ! write ("Usage: call \n") ; ! return 1 ; ! } ! // This is going to reset the clock: so we want to force the mc to ! // clear the clock first. ! if (endtime!=0) { ! write ("The clock is running. You must reset the clock first.\n") ; ! return 1 ; ! } ! if (timestr=="minutes") { ! i = i * 60 ; ! } else { ! if (timestr!="seconds") { ! write ("Enter the time in minutes or seconds.\n") ; ! return 1 ; ! } ! } ! vote_str = subjstr ; ! // This is a secret ballot so we don't want to log the votes. ! votelog = 0 ; ! write ("You call for a vote on "+vote_str+".\n") ; ! say (capitalize(mc)+" calls for a vote on "+vote_str+".\n") ; ! say (capitalize(mc)+" sets the clock to "+str+".\n") ; ! endtime = time()+i ; ! // Call out to a function which totals the votes at the end of the vote time. ! call_out ("expire_vote",i) ; ! return 1 ; ! } ! ! // Call_for_roll is exactly like call_for_vote EXCEPT that it calls for ! // a roll-call vote: that is, all votes are announced and logged. ! int call_for_roll (string str) { ! ! string timestr, subjstr ; ! int i ; ! ! if ( mc != this_player()->GetKeyName() ) { ! write ("Only the mc may call for votes.\n") ; ! return 1 ; ! } ! if (!str) { ! write ("Usage: rollcall \n") ; ! return 1 ; ! } ! if (sscanf(str,"%d %s %s",i,timestr,subjstr)!=3) { ! write ("Usage: rollcall \n") ; ! return 1 ; ! } ! if (endtime!=0) { ! write ("The clock is running. You must reset the clock first.\n") ; ! return 1 ; ! } ! if (timestr=="minutes") { ! i = i * 60 ; ! } else { ! if (timestr!="seconds") { ! write ("Enter the time in minutes or seconds.\n") ; ! return 1 ; ! } ! } ! vote_str = subjstr ; ! // This is a roll call vote so we log the votes and announce them. ! votelog = 1 ; ! write ("You call for a roll call vote on "+vote_str+".\n") ; ! say (capitalize(mc)+" calls for a roll call vote on "+vote_str+".\n") ; ! say (capitalize(mc)+" sets the clock to "+str+".\n") ; ! endtime = time()+i ; ! call_out ("expire_vote",i) ; ! return 1 ; ! } ! ! // Expire_vote finishes the vote and tabulates the results. It does not ! // announce the outcome because some votes required 2/3 or 3/4 to pass ! // rather than a simple majority. ! int expire_vote() { ! tell_room (environment(this_object()), "The clock runs out. Voting is over.\n") ; ! endtime = 0 ; ! tell_room (environment(this_object()), "The results of the vote were:\n"+ ! "Yes: "+votes["yes"]+" No: "+votes["no"]+" Abstain: "+ ! votes["abstain"]+"\n") ; ! voters = ({ }) ; ! votes["yes"] = 0 ; ! votes["no"] = 0 ; ! votes["abstain"] = 0 ; ! vote_str="none" ; ! } ! ! int localupdate() { ! write ("You may not update objects while in the conference room.\n") ; ! return 1 ; ! } diff -c -r --new-file ds2.0r26/lib/domains/campus/room/access0.c ds2.0r29/lib/domains/campus/room/access0.c *** ds2.0r26/lib/domains/campus/room/access0.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/room/access0.c Wed Jul 5 00:01:11 2006 *************** *** 36,44 **** AddExit("south","/domains/campus/room/access4"); } int CanReceive(object ob){ ! string str; ! str=file_name(environment(ob)); ! if(ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } --- 36,42 ---- AddExit("south","/domains/campus/room/access4"); } int CanReceive(object ob){ ! if(ob && ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } diff -c -r --new-file ds2.0r26/lib/domains/campus/room/conf.c ds2.0r29/lib/domains/campus/room/conf.c *** ds2.0r26/lib/domains/campus/room/conf.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/room/conf.c Wed Jul 5 00:01:11 2006 *************** *** 31,42 **** SetExits( (["north" : "/domains/campus/room/corridor4", ])); SetObviousExits("n"); ! // SetInventory((["/domains/campus/obj/podium" : 1, ! // ])); SetProperty("no attack", 1); } int CanReceive(object ob) { ! if(living(ob)){ if(file_name(environment(ob)) != "/domains/campus/room/corridor4" && !archp(ob)){ message("info","You must enter the conference room through the normal "+ --- 31,42 ---- SetExits( (["north" : "/domains/campus/room/corridor4", ])); SetObviousExits("n"); ! SetInventory((["/domains/campus/obj/podium" : 1, ! ])); SetProperty("no attack", 1); } int CanReceive(object ob) { ! if(ob && living(ob)){ if(file_name(environment(ob)) != "/domains/campus/room/corridor4" && !archp(ob)){ message("info","You must enter the conference room through the normal "+ diff -c -r --new-file ds2.0r26/lib/domains/campus/room/conf2.c ds2.0r29/lib/domains/campus/room/conf2.c *** ds2.0r26/lib/domains/campus/room/conf2.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/campus/room/conf2.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,128 ---- + #include + #include + + inherit LIB_ROOM; + + int privacy, timer; + string ExtraDesc(); + static void create() { + string privs; + privs = query_privs(); + if( privs ) privs = capitalize(privs); + else privs = "a creator"; + room::create(); + SetClimate("indoors"); + SetAmbientLight(40); + SetShort("Conference Room"); + SetLong((: ExtraDesc :)); + SetExits( ([ + ]) ); + SetInventory(([ + "/domains/town/obj/bbucket" : 1, + "/domains/town/obj/chair" : 4, + "/domains/campus/obj/podium" : 1, + ])); + + SetProperties(([ + "no attack" : 1, + "nopeer" : 1, + ])); + privacy=0; + set_heart_beat(20); + timer = 0; + + } + + int AutoDeactivate(){ + message("info","%^RED%^The privacy field shuts off.%^RESET%^", this_object()); + timer = 0; + privacy = 0; + return 1; + } + + void init(){ + ::init(); + // add_action("privacy","privacy"); + // add_action("privacy","priv"); + add_action("report_time","timer"); + } + + void heart_beat(){ + if(timer && (time() - timer ) > 1200) AutoDeactivate(); + } + + int report_time(){ + int secs = time() - timer; + //tc("time: "+time()); + //tc("timer: "+timer); + + if(!timer){ + write("Privacy field is not active."); + return 1; + } + + write("Elapsed seconds: "+secs); + write("Elapsed minutes: "+(secs/60)); + return secs; + } + + int CanReceive(object ob) { + if(privacy){ + if(!interactive(ob)) { + message("info","\n\nPRIVACY WARNING: "+ob->GetName()+" has entered the room.\n\n",this_object() ); + } + else if(!archp(ob)){ + message("info","You bounce off the conference room privacy shield.", ob); + message("info",ob->GetName()+" bounced off the privacy shield.",this_object()); + if(!environment(ob)) ob->eventMoveLiving(ROOM_START); + return 0; + } + + } + return 1; + } + + int set_privacy(int i){ + if(environment(this_player()) != this_object() && !archp(this_player())) { + write("You lack the adequate privileges to do that."); + say(this_player()->GetName()+" is trying to mess around with the privacy shield system."); + return 1; + } + privacy=i; + timer = time(); + return 1; + } + /* + int privacy(string str){ + if(environment(this_player()) != this_object() && !archp(this_player())) { + write("You lack the adequate privileges to do that."); + say(this_player()->GetName()+" is trying to muck around with the privacy shield system."); + return 1; + } + + if(str=="on" || str == "1"){ + this_object()->set_privacy(1); + write("You enable the privacy shield.\n"); + say(this_player()->GetName()+" enables a privacy force field around the room."); + timer = time(); + return 1; + } + if(str=="off" || str == "0"){ + this_object()->set_privacy(0); + write("You disable the privacy shield.\n"); + say(this_player()->GetName()+" disables a privacy force field around the room."); + timer = 0; + return 1; + } + } + */ + int get_privacy(){ + return privacy; + } + + string ExtraDesc(){ + string extra = "%^YELLOW%^A privacy force field is active around this room.%^RESET%^"; + string desc = "This is an enchanted room, with the magical power to prevent uninvited people from entering. It is used for meetings where three or more people need to share information without interruption or privately. To enable privacy, 'privacy on'. To disable it, 'privacy off'. The privacy field automatically deactivates after approximately 20 minutes.\n"; + if(privacy) return desc+extra; + else return desc+"%^RED%^The privacy field is DISABLED."; + } diff -c -r --new-file ds2.0r26/lib/domains/campus/room/corridor.c ds2.0r29/lib/domains/campus/room/corridor.c *** ds2.0r26/lib/domains/campus/room/corridor.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/room/corridor.c Wed Jul 5 00:01:11 2006 *************** *** 23,29 **** SetDoor("south", "/domains/campus/doors/plain_door"); } int CanReceive(object ob) { ! if(ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } --- 23,29 ---- SetDoor("south", "/domains/campus/doors/plain_door"); } int CanReceive(object ob) { ! if(ob && ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } diff -c -r --new-file ds2.0r26/lib/domains/campus/room/corridor3.c ds2.0r29/lib/domains/campus/room/corridor3.c *** ds2.0r26/lib/domains/campus/room/corridor3.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/room/corridor3.c Wed Jul 5 00:01:11 2006 *************** *** 23,31 **** SetProperty("no attack", 1); } int CanReceive(object ob){ ! string str; ! str=file_name(environment(ob)); ! if(ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } --- 23,29 ---- SetProperty("no attack", 1); } int CanReceive(object ob){ ! if(ob && ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } diff -c -r --new-file ds2.0r26/lib/domains/campus/room/corridor4.c ds2.0r29/lib/domains/campus/room/corridor4.c *** ds2.0r26/lib/domains/campus/room/corridor4.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/room/corridor4.c Wed Jul 5 00:01:11 2006 *************** *** 1,4 **** --- 1,5 ---- #include + #include inherit LIB_ROOM; static void create() { *************** *** 22,31 **** SetProperty("no attack", 1); } int CanReceive(object ob){ ! string str; ! str=file_name(environment(ob)); ! if(ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } return 1; --- 23,31 ---- SetProperty("no attack", 1); } int CanReceive(object ob){ ! if(ob && ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); + if(!environment(ob) && interactive(ob)) ob->eventMove(ROOM_START); return 0; } return 1; diff -c -r --new-file ds2.0r26/lib/domains/campus/room/foyer.c ds2.0r29/lib/domains/campus/room/foyer.c *** ds2.0r26/lib/domains/campus/room/foyer.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/room/foyer.c Wed Jul 5 00:01:11 2006 *************** *** 28,34 **** SetProperty("no attack", 1); } int CanReceive(object ob) { ! if(ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } --- 28,34 ---- SetProperty("no attack", 1); } int CanReceive(object ob) { ! if(ob && ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } diff -c -r --new-file ds2.0r26/lib/domains/campus/room/furnace.c ds2.0r29/lib/domains/campus/room/furnace.c *** ds2.0r26/lib/domains/campus/room/furnace.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/room/furnace.c Wed Jul 5 00:01:11 2006 *************** *** 18,24 **** SetNoModify(1); } int CanReceive(object ob){ ! if(interactive(ob)){ tell_object(ob, "You fail to enter the furnace."); return 0; } --- 18,24 ---- SetNoModify(1); } int CanReceive(object ob){ ! if(ob && interactive(ob)){ tell_object(ob, "You fail to enter the furnace."); return 0; } diff -c -r --new-file ds2.0r26/lib/domains/campus/room/mailroom.c ds2.0r29/lib/domains/campus/room/mailroom.c *** ds2.0r26/lib/domains/campus/room/mailroom.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/room/mailroom.c Wed Jul 5 00:01:11 2006 *************** *** 43,49 **** } } mixed CanMail(object who, string args) { ! if( !interactive(who) ) return 0; if( GetTown() != (string)who->GetTown() ) return "Any mail you might have will be at your home post office."; return 1; --- 43,49 ---- } } mixed CanMail(object who, string args) { ! if( who && !interactive(who) ) return 0; if( GetTown() != (string)who->GetTown() ) return "Any mail you might have will be at your home post office."; return 1; *************** *** 63,75 **** return 1; } int CanReceive(object ob) { ! if( !ob && !(ob = previous_object()) ) return 0; ! if( living(ob) && !interactive(ob) ) return 0; else return room::CanReceive(ob); } int eventReleaseObject() { object ob; if( !(ob = previous_object()) ) return room::eventReleaseObject(); if( !room::eventReleaseObject() ) return 0; if( (ob = present(POSTAL_ID, ob)) ) ob->eventDestruct(); --- 63,75 ---- return 1; } int CanReceive(object ob) { ! if( !ob || (living(ob) && !interactive(ob)) ) return 0; else return room::CanReceive(ob); } int eventReleaseObject() { object ob; + if(!ob) return 0; if( !(ob = previous_object()) ) return room::eventReleaseObject(); if( !room::eventReleaseObject() ) return 0; if( (ob = present(POSTAL_ID, ob)) ) ob->eventDestruct(); diff -c -r --new-file ds2.0r26/lib/domains/campus/room/slab.c ds2.0r29/lib/domains/campus/room/slab.c *** ds2.0r26/lib/domains/campus/room/slab.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/room/slab.c Wed Jul 5 00:01:11 2006 *************** *** 42,48 **** } int CanReceive(object ob) { ! return room::CanReceive(); } void init(){ --- 42,49 ---- } int CanReceive(object ob) { ! if(!ob) return 0; ! return room::CanReceive(ob); } void init(){ diff -c -r --new-file ds2.0r26/lib/domains/campus/room/start.c ds2.0r29/lib/domains/campus/room/start.c *** ds2.0r26/lib/domains/campus/room/start.c Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/room/start.c Wed Jul 5 00:01:11 2006 *************** *** 8,17 **** SetAmbientLight(30); SetShort("LPC University Reception"); SetLong("You are in the small, spare reception area of the Virtual Campus admissions office. A door leads north to the main administration building corridor."); ! SetNoModify(0); ! SetExits( ([ "north" : "/domains/campus/room/corridor", ]) ); SetDoor("north","/domains/campus/doors/plain_door"); SetInventory(([ "/domains/campus/obj/bbucket" :1, --- 8,17 ---- SetAmbientLight(30); SetShort("LPC University Reception"); SetLong("You are in the small, spare reception area of the Virtual Campus admissions office. A door leads north to the main administration building corridor."); ! SetExits( ([ "north" : "/domains/campus/room/corridor", ]) ); + SetNoModify(1); SetDoor("north","/domains/campus/doors/plain_door"); SetInventory(([ "/domains/campus/obj/bbucket" :1, *************** *** 25,35 **** } mixed CanReceive(object ob){ ! if(ob->GetRace() == "verb"){ ! return 0; ! } ! ! if(ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } --- 25,31 ---- } mixed CanReceive(object ob){ ! if(ob && ob->GetRace() == "rodent"){ message("info","You are repelled by rodenticide.",ob); return 0; } diff -c -r --new-file ds2.0r26/lib/domains/campus/txt/moochers.txt ds2.0r29/lib/domains/campus/txt/moochers.txt *** ds2.0r26/lib/domains/campus/txt/moochers.txt Sun Jun 18 15:50:03 2006 --- ds2.0r29/lib/domains/campus/txt/moochers.txt Wed Jul 5 00:01:11 2006 *************** *** 1 **** ! Four:One:Jayren:Seven:Solitaire:Selene:Testymage:Bastion:Testylus:testiers:EOF --- 1 ---- ! Testylus:EOF diff -c -r --new-file ds2.0r26/lib/domains/default/armor/badge.c ds2.0r29/lib/domains/default/armor/badge.c *** ds2.0r26/lib/domains/default/armor/badge.c Mon Jan 23 08:51:04 2006 --- ds2.0r29/lib/domains/default/armor/badge.c Sun Jul 9 22:06:36 2006 *************** *** 7,13 **** static void create(){ armor::create(); SetKeyName("visitor pass"); ! SetId(({"testchar badge","badge","pass","visitor pass"})); SetShort("a test character Visitor's Pass"); SetLong("This clip-on plastic badge grants the wearer access to "+ "some areas typically restricted to creator staff only. Abuse of this "+ --- 7,13 ---- static void create(){ armor::create(); SetKeyName("visitor pass"); ! SetId(({"testchar badge","badge","pass","visitor's pass"})); SetShort("a test character Visitor's Pass"); SetLong("This clip-on plastic badge grants the wearer access to "+ "some areas typically restricted to creator staff only. Abuse of this "+ diff -c -r --new-file ds2.0r26/lib/domains/default/armor/wizard_hat.c ds2.0r29/lib/domains/default/armor/wizard_hat.c *** ds2.0r26/lib/domains/default/armor/wizard_hat.c Wed Apr 5 19:33:16 2006 --- ds2.0r29/lib/domains/default/armor/wizard_hat.c Sun Jul 9 22:06:36 2006 *************** *** 5,12 **** static void create(){ armor::create(); ! SetKeyName("wizards hat"); ! SetAdjectives( ({"wizards", "floppy", "large", "conical", "blue"}) ); SetId( ({"hat"}) ); SetShort("a wizard's hat"); SetLong("This is a large, floppy hat with a wide brim all "+ --- 5,12 ---- static void create(){ armor::create(); ! SetKeyName("wizard's hat"); ! SetAdjectives( ({"wizard","wizards", "floppy", "large", "conical", "blue"}) ); SetId( ({"hat"}) ); SetShort("a wizard's hat"); SetLong("This is a large, floppy hat with a wide brim all "+ diff -c -r --new-file ds2.0r26/lib/domains/default/npc/dummy.c ds2.0r29/lib/domains/default/npc/dummy.c *** ds2.0r26/lib/domains/default/npc/dummy.c Sun Jun 18 16:20:52 2006 --- ds2.0r29/lib/domains/default/npc/dummy.c Sun Jul 9 19:04:27 2006 *************** *** 29,48 **** evidence = ""; if(agent) evidence += "I receive damage from "+agent->GetKeyName(); if(type) { ! if(type == BLUNT ) evidence += ", damage type is BLUNT"; ! if(type == BLADE ) evidence += ", damage type is BLADE"; ! if(type == KNIFE ) evidence += ", damage type is KNIFE"; ! if(type == WATER ) evidence += ", damage type is WATER"; ! if(type == SHOCK ) evidence += ", damage type is SHOCK"; ! if(type == COLD ) evidence += ", damage type is COLD"; ! if(type == HEAT ) evidence += ", damage type is HEAT"; ! if(type == GAS ) evidence += ", damage type is GAS"; ! if(type == ACID ) evidence += ", damage type is ACID"; ! if(type == MAGIC ) evidence += ", damage type is MAGIC"; ! if(type == POISON ) evidence += ", damage type is POISON"; ! if(type == DISEASE ) evidence += ", damage type is DISEASE"; ! if(type == TRAUMA ) evidence += ", damage type is TRAUMA"; ! //else evidence += ", damage type is indeterminate"; } if(x) evidence += ", raw damage is "+x; if(internal) evidence += ", internal variable is "+internal; --- 29,58 ---- evidence = ""; if(agent) evidence += "I receive damage from "+agent->GetKeyName(); if(type) { ! switch(type){ ! case BLUNT : evidence += ", damage type is BLUNT";break; ! case BLADE : evidence += ", damage type is BLADE";break; ! case KNIFE : evidence += ", damage type is KNIFE";break; ! case WATER : evidence += ", damage type is WATER";break; ! case SHOCK : evidence += ", damage type is SHOCK";break; ! case COLD : evidence += ", damage type is COLD";break; ! case HEAT : evidence += ", damage type is HEAT";break; ! case GAS : evidence += ", damage type is GAS";break; ! case ACID : evidence += ", damage type is ACID";break; ! case MAGIC : evidence += ", damage type is MAGIC";break; ! case POISON : evidence += ", damage type is POISON";break; ! case DISEASE : evidence += ", damage type is DISEASE";break; ! case TRAUMA : evidence += ", damage type is TRAUMA";break; ! case PIERCE : evidence += ", damage type is PIERCE";break; ! case PSIONIC : evidence += ", damage type is PSIONIC";break; ! case ANOXIA : evidence += ", damage type is ANOXIA";break; ! case DEATHRAY : evidence += ", damage type is DEATHRAY";break; ! case EMOTIONAL : evidence += ", damage type is EMOTIONAL";break; ! case SONIC : evidence += ", damage type is SONIC";break; ! case BITE : evidence += ", damage type is BITE";break; ! case OTHER : evidence += ", damage type is OTHER";break; ! default : evidence += ", damage type is UNKNOWN";break; ! } } if(x) evidence += ", raw damage is "+x; if(internal) evidence += ", internal variable is "+internal; diff -c -r --new-file ds2.0r26/lib/domains/default/npc/fighter.c ds2.0r29/lib/domains/default/npc/fighter.c *** ds2.0r26/lib/domains/default/npc/fighter.c Fri Mar 24 14:36:36 2006 --- ds2.0r29/lib/domains/default/npc/fighter.c Sat Jul 8 23:30:54 2006 *************** *** 9,23 **** SetLong("This is a large human warrior. His pectoral muscles "+ "are clearly visible even through his armor. His face is covered in "+ "bold blue tattoos."); ! SetCustomXP(350); SetLevel(10); SetRace("human"); - SetClass("fighter"); SetGender("male"); SetInventory(([ "/domains/default/armor/chainmail.c" : "wear chainmail", "/domains/default/weap/sharpsword.c" : "wield sword" ])); SetMaxHealthPoints(550); } void init(){ --- 9,27 ---- SetLong("This is a large human warrior. His pectoral muscles "+ "are clearly visible even through his armor. His face is covered in "+ "bold blue tattoos."); ! SetClass("fighter"); SetLevel(10); + SetCustomXP(350); SetRace("human"); SetGender("male"); SetInventory(([ "/domains/default/armor/chainmail.c" : "wear chainmail", "/domains/default/weap/sharpsword.c" : "wield sword" ])); + SetCurrency( ([ + "silver" : 100, + ]) ); + SetHealthPoints(549); SetMaxHealthPoints(550); } void init(){ diff -c -r --new-file ds2.0r26/lib/domains/default/npc/tree.c ds2.0r29/lib/domains/default/npc/tree.c *** ds2.0r26/lib/domains/default/npc/tree.c Thu Feb 23 15:40:40 2006 --- ds2.0r29/lib/domains/default/npc/tree.c Sat Jul 8 23:30:54 2006 *************** *** 11,19 **** --- 11,21 ---- "pods are full to bursting with coins of all kinds. It would be no "+ "trouble at all to get from tree...looks like "+ "you've hit the jackpot!"); + SetPacifist(1); SetCanBite(0); SetLevel(99); SetRace("tree"); + SetHealthPoints(99999); SetMaxHealthPoints(99999); } void init(){ diff -c -r --new-file ds2.0r26/lib/domains/default/obj/guide.c ds2.0r29/lib/domains/default/obj/guide.c *** ds2.0r26/lib/domains/default/obj/guide.c Sun Jun 18 16:20:53 2006 --- ds2.0r29/lib/domains/default/obj/guide.c Sun Jul 9 22:06:36 2006 *************** *** 4,12 **** void create(){ ::create(); ! SetKeyName("guidebook"); SetId( ({"book", "guide", "administrators guide", "administrators guidebook"}) ); ! SetAdjectives( ({"admin", "admins", "administrator", "administrators", "reference"}) ); SetShort("an Administrator's Guidebook"); SetLong("This is a reference text for Dead Souls administrators."); SetNoCondition(1); --- 4,12 ---- void create(){ ::create(); ! SetKeyName("administrator's guidebook"); SetId( ({"book", "guide", "administrators guide", "administrators guidebook"}) ); ! SetAdjectives( ({"admin's", "admin", "admins", "administrator", "administrators", "reference"}) ); SetShort("an Administrator's Guidebook"); SetLong("This is a reference text for Dead Souls administrators."); SetNoCondition(1); diff -c -r --new-file ds2.0r26/lib/domains/default/room/arena.c ds2.0r29/lib/domains/default/room/arena.c *** ds2.0r26/lib/domains/default/room/arena.c Mon Jan 23 08:51:42 2006 --- ds2.0r29/lib/domains/default/room/arena.c Wed Jul 5 00:01:11 2006 *************** *** 6,12 **** SetClimate("indoors"); SetAmbientLight(30); SetShort("the Arena"); ! SetLong("You are in a large room with blank cement walls. This room was built so Creators may test their armor, weapons and NPC's in combat."); SetItems( ([ ({"wall","walls"}) : "The walls are smooth and cement.", ({"floor","ceiling"}) : "The floor and ceiling are, like the walls, made "+ --- 6,12 ---- SetClimate("indoors"); SetAmbientLight(30); SetShort("the Arena"); ! SetLong("You are in a large room with blank cement walls. This room was built so Creators may test their armor, weapons and NPC's in combat. A large steel door is here, which can be used to prevent wimpy creatures from escaping."); SetItems( ([ ({"wall","walls"}) : "The walls are smooth and cement.", ({"floor","ceiling"}) : "The floor and ceiling are, like the walls, made "+ diff -c -r --new-file ds2.0r26/lib/domains/default/room/domains_room.c ds2.0r29/lib/domains/default/room/domains_room.c *** ds2.0r26/lib/domains/default/room/domains_room.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/default/room/domains_room.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,66 ---- + #include + #include + + inherit LIB_ROOM; + + string LongDesc(){ + string desc = "Immortals come here to communicate with each other about "+ + "the world they are building. The Adventurer's Guild "+ + "is north. The Arch Room is south. To visit the Dead Souls "+ + "test and development mud, go west. The test lab facilities are east."; + desc += "\nA sign reads: "+load_object(ROOM_ARCH)->SignRead(); + return desc; + } + + static void create() { + object ob; + room::create(); + SetClimate("indoors"); + SetAmbientLight(30); + SetShort("Domains Room"); + SetLong("This room provides a convenient access point to various domain start rooms and featured realms."); + SetItems(([ + "Ylsrim" : "This is the entry point for the Ylsrim domain.", + "campus" : "This is the entry point for the campus domain.", + "examples" : "This is the entry point for the examples domain.", + ({ "sign" }) : "A sign you can read.", + ])); + SetEnters( ([ + "campus" : "/domains/campus/room/start", + "ylsrim" : "/domains/Ylsrim/room/bazaar", + "examples" : "/domains/examples/room/start.c", + ]) ); + SetProperty("no attack", 1); + SetProperty("nopeer",1); + ob = new("/lib/bboard"); + ob->SetKeyName("chalkboard"); + ob->SetId( ({ "board", "chalkboard", "dusty board", "dusty chalkboard" }) ); + ob->set_board_id("immortal_board"); + ob->set_max_posts(30); + SetShort("Domains Room"); + ob->eventMove(this_object()); + SetExits(([ + "north" : "/domains/default/room/wiz_hall2", + ])); + + SetInventory(([ + ])); + + SetRead("sign", (: load_object(ROOM_ARCH)->SignRead() :) ); + } + + int CanReceive(object ob) { + if(playerp(ob) && !creatorp(ob) && !present("testchar badge",ob)) { + message("info","Creator staff only, sorry.", ob); + return 0; + } + + if(ob->GetRace() == "rodent"){ + message("info","You are repelled by rodenticide.",ob); + return 0; + } + return 1; + } + void init(){ + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/default/room/telnet_room.c ds2.0r29/lib/domains/default/room/telnet_room.c *** ds2.0r26/lib/domains/default/room/telnet_room.c Tue Mar 28 23:23:40 2006 --- ds2.0r29/lib/domains/default/room/telnet_room.c Wed Jul 5 00:01:11 2006 *************** *** 41,51 **** "Once you connect to Dead Souls, type \"dcon\" to "+ "return to your own mud. \n\n"+ "To connect type \"connect\" \n"+ ! "The Creators' Hall is east of here."); ! SetExits( ([ ! "east" : "/domains/default/room/wiz_hall" ]) ); - SetObviousExits("e"); SetNoModify(1); } --- 41,50 ---- "Once you connect to Dead Souls, type \"dcon\" to "+ "return to your own mud. \n\n"+ "To connect type \"connect\" \n"+ ! "The Creators' Hall west wing is south of here."); ! SetExits( ([ ! "south" : "/domains/default/room/wiz_hall2", ]) ); SetNoModify(1); } diff -c -r --new-file ds2.0r26/lib/domains/default/room/wiz_hall.c ds2.0r29/lib/domains/default/room/wiz_hall.c *** ds2.0r26/lib/domains/default/room/wiz_hall.c Fri Mar 24 14:36:36 2006 --- ds2.0r29/lib/domains/default/room/wiz_hall.c Wed Jul 5 00:01:11 2006 *************** *** 34,44 **** SetItems( ([ ({"sign"}) : "A sign you can read.", ]) ); ! SetExits( ([ ! "north" : "/domains/town/room/adv_guild", "east" : "/domains/default/room/wiz_corr1", "south" : "/secure/room/arch", ! "west" : "/domains/default/room/telnet_room", ]) ); SetRead("sign", (: load_object(ROOM_ARCH)->SignRead() :) ); } --- 34,44 ---- SetItems( ([ ({"sign"}) : "A sign you can read.", ]) ); ! SetExits( ([ "east" : "/domains/default/room/wiz_corr1", "south" : "/secure/room/arch", ! "north" : "/domains/town/room/adv_guild", ! "west" : "/domains/default/room/wiz_hall2.c", ]) ); SetRead("sign", (: load_object(ROOM_ARCH)->SignRead() :) ); } diff -c -r --new-file ds2.0r26/lib/domains/default/room/wiz_hall2.c ds2.0r29/lib/domains/default/room/wiz_hall2.c *** ds2.0r26/lib/domains/default/room/wiz_hall2.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/default/room/wiz_hall2.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,59 ---- + #include + #include + + inherit LIB_ROOM; + + string LongDesc(){ + string desc = "Immortals come here to communicate with each other about "+ + "the world they are building. The Adventurer's Guild "+ + "is north. The Arch Room is south. To visit the Dead Souls "+ + "test and development mud, go west. The test lab facilities are east."; + desc += "\nA sign reads: "+load_object(ROOM_ARCH)->SignRead(); + return desc; + } + + static void create() { + object ob; + room::create(); + SetClimate("indoors"); + SetAmbientLight(30); + SetShort("Creators' Hall West Wing"); + SetLong("This is the west wing of the Creators' Hall. North is the telnet room where you can connect to the Dead Souls test and development mud. South is the domains room, where you can conveniently visit featured domains or realms."); + SetProperty("no attack", 1); + SetProperty("nopeer",1); + ob = new("/lib/bboard"); + ob->SetKeyName("chalkboard"); + ob->SetId( ({ "board", "chalkboard", "dusty board", "dusty chalkboard" }) ); + ob->set_board_id("immortal_board"); + ob->set_max_posts(30); + SetShort("Creators' Hall West Wing"); + ob->eventMove(this_object()); + SetItems( ([ + ({"sign"}) : "A sign you can read.", + ]) ); + SetExits( ([ + "east" : "/domains/default/room/wiz_hall", + "north" : "/domains/default/room/telnet_room", + "south" : "/domains/default/room/domains_room.c", + ]) ); + SetInventory(([ + ])); + + SetRead("sign", (: load_object(ROOM_ARCH)->SignRead() :) ); + } + + int CanReceive(object ob) { + if(playerp(ob) && !creatorp(ob) && !present("testchar badge",ob)) { + message("info","Creator staff only, sorry.", ob); + return 0; + } + + if(ob->GetRace() == "rodent"){ + message("info","You are repelled by rodenticide.",ob); + return 0; + } + return 1; + } + void init(){ + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/examples/room/README ds2.0r29/lib/domains/examples/room/README *** ds2.0r26/lib/domains/examples/room/README Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/README Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,16 ---- + Example Rooms Index + =========================================================================== + exroom1: Changing Chats when a quest has been done. + exroom2: example of a room you can inherit. All its functions + go to the rooms which inherit it. They can over-write those functions. + All three rooms which inherit it manipulate 'pull' in their own + rooms. They don't affect 'pull' or "myvar" in this room. + exroom2a: inherits exroom2 and ADDS to the object_entered function + exroom2b: inherits exroom2 and adds nothing to object_entered (but you'll + see that it uses the object_entered from exroom2). + exroom2c: inherits exroom2 and removes the object_entered from exroom2. + exroom3: move_player + exroom4: pre/post exits add/remove exits set/query/remove tempvars + exroom5: look_fail & tempvars pt 2. + exroom6: pre-exit (sneak) + exroom7: two verbs for one add_action diff -c -r --new-file ds2.0r26/lib/domains/examples/room/entrance.c ds2.0r29/lib/domains/examples/room/entrance.c *** ds2.0r26/lib/domains/examples/room/entrance.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/entrance.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,106 ---- + #include + #include + #include "ex.h" + + inherit LIB_ROOM; + + + void create() { + room::create(); + SetAmbientLight(30); + SetShort( "Entrance to Hall Of Rooms" ); + SetLong( + "|-----------------------------------------------------------------------------|\n\n"+ + " You are in a large, empty room. There are few things to examine -- only the\n" + "floor, ceiling and wall at this time. An opening to your north leads to the \n" + "incredible Hall of Examples. The line at the top of this description was put\n" + "in as a VERY useful tool for keeping a standard width to all descriptions\n" + " and messages.\n\n" + " The Hall of Examples has many rooms to look through. Each room is limited\n" + "to one or two different types of things. For example, showing how to do a\n" + "pre-exit function. Naturally, you will probably combine many of these\n" + "functions into one single room. Room files can get long and involved, but\n" + "when you understand the individual parts, you have no trouble understanding\n" + "the whole. Don't forget to %^BOLD%^GREEN%^'more here'%^RESET%^ in each room." + " Most of the rooms have explanations written out in comments.\n\n" + " As a final aside, most of the functions are simplistic. These are \n" + "very basic examples." + ); + + SetExits( ([ + "north" : EXPATH + "exroom1", + "south" : START + ])); + + // What follows is a short tutorial on item descriptions. + + // A mapping is a special type of variable -- a list. + // It has a 'key' and a 'value' which are tied together. + // When you query a key it returns the value. + // Each key must be unique. + + // The SetItems in rooms is a mapping where the key & value are + // both strings. + + // This: ([ ]) means what is inside is a mapping. + + // SetItems( ([ ]) ); means you're putting an entire + // mapping into the SetItems. This is how we put items into + // various rooms. We're manipulating the entire mapping + // as a whole. You'll notice for the walls, there is an + // array to allow a player to do 'look wall' and 'look walls' + // and get the same description. This is a very useful method. + + SetItems( ([ + "floor" : "The floor is dirty.", + "ceiling" : "The ceiling is high", + ({ "wall", "walls" }) : "The walls are currtly not very exciting.", + ]) ); + + // The room code also allows us to manipulate individual 'keys' of the + // SetItems mapping: + // AddItem( "bird" , "A small robin sits passageway you can enter."); + // would be a way to put the description for bird into the SetItems mapping. + + // With any mapping, when you set a value for a key that already exists + // the mapping replaces the old one with the new; if that key does + // not yet exist it will add it in. + + // So, when you see the ([ ]) it means you are plunking in a group of + // key/value pairs into the mapping. + + // Finally, if you do SetItems( ([ ]) ); it is going to replace + // the entire SetItems mapping with what is in the ([ ]). + // If you do AddItem(); it will ADD the new mapping to + // the existing SetItems mapping. + + // To illustrate you need to call the test1() function in this room. + // To do that, do the following: + // > call here->test1() + + } + + void test1() + { + write("Now take a look at the room"); + SetItems( ([ + "north wall" : "The north wall has an exit.", + "east wall" : "The east wall is painted blue.", + "south wall" : "The south wall is painted yellow.", + "west wall" : "The west wall is painted green.", + "wall" : "Which wall? North, South, East or West?", + "walls" : "Which wall? North, South, East or West?" + ]) ); + + // In this example, when overwriting the SetItems mapping, you are + // not able to use arrays at this time. That is the reason that + // 'wall' and 'walls' is not listed as you first saw. Keep this + // in mind when overwriting existing mappings. As you'll also + // notice, as mentioned above, you can no longer look at the floor + // or the ceiling since the whole SetItems mapping has been replaced. + + // Now let's add one description to the list. + AddItem( "statue", "There is a statue of a wizard here." ); + + return; + } diff -c -r --new-file ds2.0r26/lib/domains/examples/room/ex.h ds2.0r29/lib/domains/examples/room/ex.h *** ds2.0r26/lib/domains/examples/room/ex.h Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/ex.h Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,7 ---- + //here's some paths + #define EXAMPLES "/domains/examples/" + #define EXPATH EXAMPLES + "room/" + + //here's some files + #define PAPAROOM EXPATH +"exroom2" + #define START EXPATH + "start" diff -c -r --new-file ds2.0r26/lib/domains/examples/room/exroom1.c ds2.0r29/lib/domains/examples/room/exroom1.c *** ds2.0r26/lib/domains/examples/room/exroom1.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/exroom1.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,110 ---- + #include + #include + #include "ex.h" + + // The #include "ex.h" is used in each of these files to remember + // the defines for EXPATH and other variables we have defined + // that all of these files use. It would be tedious to have to + // put the #define EXPATH in every file, so we put it into one + // and include it as a reference for each file that needs it. + // Consider it a library card. The books that are in the library + // (the #define's) are referenced every time you see EXPATH. + + inherit LIB_ROOM; + + // I'm defining a global variable here called once to be used later + // in the file. A global variable is something that can be used + // by any function in this room. There are also local variables + // that can be defined only in the variable using it. + + int once; + + // I'm also defing a function lever_pulled() that will be called later. + mixed lever_pulled(); + + void create() + { + ::create(); + SetAmbientLight(30); + SetShort( "Lever Pull" ); + SetLong("This is an example room for a simple add_action which changes "+ + "a description. There's a lever to pull." + ); + + SetExits( ([ + "north" : EXPATH + "exroom2", + "south" : EXPATH + "entrance", + ])); + + // Here, take a look at how I set the lever item. It is different + // that you saw in the entrance room. What I am doing here is + // calling a functional. When the player types 'look lever', it + // will call the functional (: lever_pulled :) that we defined above. + // I'll explain later in this file. + + SetItems( ([ + "lever" : ((: lever_pulled :)) + ]) ); + + } + + // In the init() function, I am setting our global variable 'once' to 0. This + // is used to reset the lever back when the room resets or the mud reboots. + // so the next player who comes in to pull the lever, they can. + // In the init() function, we also define the actions that can be done in the + // room. In this case, we need a pull action to 'pull lever'. Whenever a player + // types pull, it will call the function aa_pull(). + + void init() + { + ::init(); + add_action("aa_pull","pull"); + once = 0; + } + + // This is the function that is called when a player types pull as mentioned above. + // First, we need to check and see if they are pulling the correct thing. the + // string str is defining a local variable that will be used in this function. + // Next, we have if( str != "lever"). That is saying if I type 'pull finger', + // it will write 'Pull what?'. The \n symbol means a carriage return or 'enter' + // to go to the next line. + + mixed aa_pull(string str) + { + if ( str != "lever") + { + write( "Pull what?\n" ); + return 1; + } + + // Here we are going to check if the lever has been pulled. If it has, + // it's going to tell the player that and exit the aa_pull() function. + // this is done by the return 1; that you see here. + + if( once ==1 ) + { + write( "The lever's already pulled." ); + return 1; + } + + // If the lever has not been pulled, this part starts. As you'll notice, we + // set once = 1 to indicate that the lever has been pulled. + + write("You pull the lever!\n"); + say(this_player()->GetName() + " pulls the lever!\n"); + once=1; + return 1; + } + + // I told you I'd explain what the functional (: lever_pulled :) was for. + // Below, it checks to see if the lever has been pulled. if( !once ) + // says, if once is equal to 0 (not pulled) it returns and says the lever + // has not been pulled. If once is not equal to 0, then it means that it + // has been pulled and returns a different message. + + mixed lever_pulled() + { + if( !once ) + return "The lever is pushed into the wall. Perhaps you could pull it."; + return "The lever has already been pulled. You're too late!"; + } diff -c -r --new-file ds2.0r26/lib/domains/examples/room/exroom2.c ds2.0r29/lib/domains/examples/room/exroom2.c *** ds2.0r26/lib/domains/examples/room/exroom2.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/exroom2.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,77 ---- + #include + #include "ex.h" + + inherit LIB_ROOM; + + int myvar; + + void create() + { + ::create(); + SetAmbientLight(30); + SetShort( "a master file" ); + SetLong(@EndText + |---------------------------------------------------------------|-------------| + This is an example room for inheriting files. This + file is inherited by two others. It's also a fully + functional room. There's a lever to pull. + The rooms which inherit me are to the east. + EndText + ); + + // You'll notice that for SetLong(), I've put @EndText at the top and EndText at the bottom + // and have not put in quotes. When using this style of code, it is important to make sure + // you manually enter to the next line to wrap the lines on the player's screen. + // This can be a tedious if you do not know how many lines to enter before you need to + // continue on the next line. If you look back to the Entrance to the Hall of Examples, + // You will see a handy line I've used to know when to stop a line and continue on + // the next. I've included it in the room description for your convenience. the + // normal screen default is 79 characters. Whenever you would like to recreate the line + // at the top, type 'margins' + + SetExits( ([ + "south" : EXPATH + "exroom1", + "north" : EXPATH + "exroom3", + "east" : EXPATH + "exroom2a" + ]) ); + SetItems( ([ + "lever" : "A lever for pulling.", + ]) ); + + myvar = 0; + } + + // The CanReceive() function is very helpful to do checks on an interactive object + // that enters the room. In this case, we are checking to see if the object that + // enters is a creator player object. If it is, then we will give a message to + // that object with the write() funciton. I've put some color tags to set the color + // off from the rest of the text. For colors available, type 'colors'. + + int CanReceive(object ob) + { + if ( creatorp(ob) ) + write( "%^BOLD%^BLUE%^Room tells you: %^BOLD%^GREEN%^You're a creator! %^BOLD%^BLUE%^(This is from the master file.)%^RESET%^\n"); + return 1; + } + + void init() + { + ::init(); + add_action("aa_pull","pull"); + } + + // We're going to use the variable 'myvar' in the middle of a write() funciton. As + // you'll notice below, the text you are writing has to be in the " ". Then we + // separate the text by putting in: " + myvar + ". This adds the myvar variable + // to the text output whenever a player pulls the lever. Try it and see. + + + mixed aa_pull(string str) + { + if (str!="lever") + return notify_fail("Pull what?\n"); + myvar ++; + write("You pull the lever and the value of 'myvar' is now " + myvar + "\n"); + say(this_player()->GetName() + " pulls the lever!\n"); + return 1; + } diff -c -r --new-file ds2.0r26/lib/domains/examples/room/exroom2a.c ds2.0r29/lib/domains/examples/room/exroom2a.c *** ds2.0r26/lib/domains/examples/room/exroom2a.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/exroom2a.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,72 ---- + #include + #include "ex.h" + + inherit PAPAROOM; + + void create() + { + ::create(); + SetAmbientLight(30); + SetShort( "a 'child' file" ); + SetLong("This is an example room whose properties are inherited " + "from another room.\n for more information." + ); + + //Note: When we set the "exits" in this room we + // over-write the "exits" we inherited from PAPAROOM + // There's a way to just add an exit to the list, but exits + // are primarily unique to each room, so this method is fine. + SetExits( ([ + "west" : EXPATH + "exroom2", + "east" : EXPATH + "exroom2b" + ])); + + SetItems( ([ + "more" : @EndBlah + ------------------------------------------------------------------- + Take a look at the CanReceive function. + Do you see the line ::CanReceive(ob)? + The :: refers to 'the file I've inherited from'. + So, we are calling (using) the function CanReceive() as it is + written in exroom2.c + THEN we are doing our own thing. + + When an object enters this room (player or bowl or sword etc) + it becomes the variable 'ob'. + + We pass that variable 'ob' along to the function CanReceive() + that's in exroom2.c + + Then we check to see if ob is a player or creator. (type: man userp) + If so, we give that object a message. + ------------------------------------------------------------------- + EndBlah, + ])); + + /* See the way I did the SetItems again for 'more'. This is one + way to do it. Another way to do it is to use a (: functional :) + like I did for the lever. Take a look, however, at this comment + that you are reading. If you'll notice, I've done it a little + differently to show you a way to comment out several lines all + at once. The original method that I used was to put // in front + of the line that I wanted to comment out. If you have several + lines like we have here, then you'll want to begin your comment + like you see here and end it like below. This is how I will + be doing large comments in future examples. + */ + + + } + + int CanReceive(object ob) + { + ::CanReceive(); + if ( userp(ob) ) + write("%^MAGENTA%^Room tells you: %^GREEN%^You're any player, creator or not! %^MAGENTA%^(This is from this room)%^RESET%^\n"); + return 1; + } + + void init() + { + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/examples/room/exroom2b.c ds2.0r29/lib/domains/examples/room/exroom2b.c *** ds2.0r26/lib/domains/examples/room/exroom2b.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/exroom2b.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,37 ---- + #include + #include "ex.h" + + inherit PAPAROOM; + + void create() + { + ::create(); + SetAmbientLight(30); + SetShort( "a 'child' file" ); + SetLong("This is an example room that inherits the properties " + "of another room."); + + /* Note: When we set the "exits" in this room we over-write + the "exits" we inherited from PAPAROOM. There's a way to + just add an exit to the list, but exits are primarily + unique to each room, so this method is fine. + */ + + SetExits( ([ + "west" : EXPATH + "exroom2a", + ])); + + /* Now, we are setting the objects that are loaded into the room, + or the inventory of the room. Just like a player has inventory + on their character. + */ + + SetInventory( ([ "/domains/default/obj/bbucket" : 1 ])); + + } + + + void init() + { + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/examples/room/exroom3.c ds2.0r29/lib/domains/examples/room/exroom3.c *** ds2.0r26/lib/domains/examples/room/exroom3.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/exroom3.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,55 ---- + #include + #include "ex.h" + + inherit LIB_ROOM; + + void create() + { + ::create(); + SetAmbientLight(30); + SetShort( "move the player" ); + SetLong(@EndText + This is an example room for moving a player. There's nothing + to look at here. But, surprise, there's a lever to pull. + + We are going to get a bit fancier and have something special + happen when a player pulls the lever. + EndText + ); + + SetExits( ([ + "south" : EXPATH + "exroom2", + "north" : EXPATH + "exroom4", + ])); + + } + + void init() + { + ::init(); + add_action("aa_pull","pull"); + } + + int aa_pull(string str) + { + if (str!="lever") + { + write( "Pull what?\n" ); + return 1; + } + write(@EndText + You pull the lever and a big hand grabs you! + It whisks you away to parts unknown. Ok, they are known. + Look around when you get there, which is basically instantaneous. + EndText); + say(this_player()->GetName() + " pulls the lever!"); + this_player()->eventMoveLiving(EXPATH + "exroom1", "forcibly when a big hand takes " + objective(this_player()) + " away", + this_player()->GetName() + " is dropped from the sky by a big hand." + ); + return 1; + } + + /* The eventMoveLiving() function transports the player who pulls + the lever to another room. It also writes a message in the room + that the player leaves and in the room they are sent to. + */ diff -c -r --new-file ds2.0r26/lib/domains/examples/room/exroom4.c ds2.0r29/lib/domains/examples/room/exroom4.c *** ds2.0r26/lib/domains/examples/room/exroom4.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/exroom4.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,198 ---- + #include + #include "ex.h" + + inherit LIB_ROOM; + int pre_north(); + int post_south(); + int post_north(); + + void create() + { + ::create(); + SetAmbientLight(30); + SetShort( "pre/post exits and add/remove exits" ); + SetLong(@EndText + There's a door to the north with a doorbell, and a blank + wall to the south. + ------------------------------------------------------------- + This is an example room for using pre-exits and post-exits. + It also shows how to add & delete an exit from the room, and + use a temporary variable on a player. + + There's a lever to pull and push, and a bell to ring. + Pull the lever out: create an exit to the south. + Push the lever in: delete an exit to the south. + Ring the bell: allows you to go north. + When you go south, the exit to the south disappears. + ------------------------------------------------------------- + EndText + ); + + SetExits( ([ + ])); + + AddExit( "north", EXPATH + "exroom5", (: pre_north :)); + + } + + void init() + { + ::init(); + add_action("aa_pull","pull"); + add_action("aa_push","push"); + add_action("aa_ring","ring"); + } + + + int aa_pull(string str) + { + if (str!="lever" && str!="lever out") + { + write( "Pull what?\n" ); + return 1; + } + /* Now, we can find out if the lever has been already pulled + in one of two ways. + Method one: we test to see if the exit to the south is open. + Since pulling the lever does this, and the only way to + create that exit is pulling the lever -- this is a valid method. + + Method two: we use a variable and change it's value when the lever + is pushed or pulled. Since we have a method that works without + using an additional variable, that is the method I'll pick here. + It will also show you how to query for an exit. + + Note: GetExits() returns a mapping for all the exits in a room + GetExit("dir") returns the value for that specific direction. + if there is NOT an exit in that direction it will return UNDEFINED + and can be detected using the ! operator. (! means 'not') + conversely, if GetExit("dir") is true, then there IS an exit + to that direction. Got it? Good. + */ + + if ( GetExit("south") ) + { + write("The lever is already pulled out!\n"); + return 1; + } + + /* If you don't know by now, this_player() indicates the player doing the actions + So when I do this_player()->GetName() it gives me the name of the player + who is doing the actions and allows me to tell the room who it is. + */ + + write( "You pull the lever and an invisible crack appears in the south wall. "+ + "A door slides open and there is a previously undetected exit." ); + say(this_player()->GetName() + " pulls the lever and an exit appears to the south.\n"); + + // AddExit() functions add an exit to the room. Here, we added an exit and + // set up a (: functional :) to do close up the exit when they leave. + + AddExit( "south", EXPATH + "exroom3", (: post_south :) ); + SetObviousExits("n, s"); + return 1; + } + + + int aa_push(string str) + { + if (str!="lever" && str!="lever in") + { + write( "Push what?\n" ); + return 1; + } + + /* Since there's more then one way for the exit to dissappear (see the post-exit + function for south) and there may be more then one player wandering the halls + we don't want to assume that 'this' player pushed the lever. So we wouldn't + say "You've already pushed the lever." + */ + + if ( ! GetExit("south") ) + { + write( "The lever is pushed in as far as it will go.\n"); + return 1; + } + write( "You push the lever in and an unseen door slides shut in the south wall."+ + "The wall now appears solid and unpenatrable." ); + say(this_player()->GetName() + " pushes the lever and the south closes tight.\n"); + + // Now we remove the exit that was added earlier. + + RemoveExit("south"); + SetObviousExits("n"); + return 1; + } + + + int aa_ring(string str) + { + if (str!="bell" && str!="doorbell" && str!="door bell") + { + write( "Ring what?\n" ); + return 1; + } + //if we only want to let them ring it once, we can check for the + //temp var here. This version will let them ring it many times. + write("DONG!\nYou ring a doorbell! You are now admitted north.\n"); + say("DONG! A doorbell rings.\n"); + this_player()->SetProperty("rung_bell", 1); + return 1; + } + + + /* CODING STYLE 101 + Personally, I always put my post/pre exit functions right after create and + before the reset() or init() functions. This makes them easy to find. + Since they're MENTIONED in the create() I like to keep 'em close at hand. + For the same reason I usually follow my init() with any add_actions that + I've created. I also preface my functions with an indicator saying what + their purpose is. I've chosen aa_ for add_actions an pe_ for pre or post + exit functions. OR i use pre_ or post_ when i have both going on. This + may not seem like a big deal in a little file, but when the file gets + huge, it helps to glance at a function and go: ah ha! this is a post_exit + function. or ah ha! this is an add_action or similarly: ah ha! this is + not any specialized function so I must be calling it for some other reason. + The order you write them in is a personal decision. Just keep your + create() function first on the list. + */ + + //A return 0 in a pre-exit will prevent you from going that dir. + //A return 1 will allow you to go that dir. + + + int pre_north() + { + if( !this_player()->GetProperty("rung_bell") ) + { + write("Ring the doorbell first!\n"); + return 0; + } + // Now that the pre_north() function has done what it needs to do, we + // will call the post_north() function here + post_north(); + return 1; + } + + + int post_north() + { + //might as well delete it, it's served its purpose. + this_player()->RemoveProperty("rung_bell"); + return 1; + } + + + //We're going to delete the exit AFTER the player walks through + // Because doing it in a pre_exit would be tatamount to slamming + // a door in their face. You wouldn't want to do that... would you? :P + + + int post_south() + { + write("You hear a noise and realize the wall has mysteriously closed.\n"); + say("You hear a noise and realize the wall has mysteriously closed.\n"); + this_player()->eventMoveLiving("/domains/examples/room/exroom3", "south", this_player()->GetName()+" enters."); + RemoveExit("south"); + SetObviousExits("n"); + } diff -c -r --new-file ds2.0r26/lib/domains/examples/room/exroom5.c ds2.0r29/lib/domains/examples/room/exroom5.c *** ds2.0r26/lib/domains/examples/room/exroom5.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/exroom5.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,139 ---- + #include + #include "ex.h" + + //LOOKIE! A constant (#define) at the top of the file instead + // of in a header (.h) file. Yes, this is possible and sometimes + // a better method. This is the only room in the entire directory + // which uses this define. It doesn't really need to go into + // the ex.h file. However, it must be at the top of the file. + + #define ORC "/domains/town/npc/orc" + + inherit LIB_ROOM; + + void create() + { + ::create(); + SetAmbientLight(30); + SetShort( "temp vars" ); + SetLong(@EndText + You can't really see north and there's a bell + on the south door. Don't ring it too many times! + ------------------------------------------------------------- + This is an example room for querying the specific value of a + stored variable. Remember though, variables are persistent. + If you want to prevent a future bug report from your players + or creators, then make sure you remove the variable when they + leave. Otherwise, when the come back in a week and ring the + bell only once, it would actually be added to their previous + rings. + ------------------------------------------------------------- + EndText + ); + + SetProperty( "no peer", 1); + + SetExits( ([ + "north" : EXPATH + "exroom6", + "south" : EXPATH + "exroom4", + ])); + } + + void init() + { + ::init(); + add_action("aa_ring","ring"); + } + + /* Since we don't need the temp var now, we will remove it. + In the CanRelease() function, I am telling the room that + when an object tries to leave, to remove the temp var + and return 1; to say that it is okay to leave. Were + I to put return 0; then the player would not be able + to leave. + */ + + int CanRelease() + { + this_player()->RemoveProperty("rung_bell"); + return 1; + } + + mixed aa_ring(string str) + { + int numrings; + if (str!="bell" && str!="doorbell" && str!="door bell") + return notify_fail("Ring what?\n"); + /* if "rung_bell" has not been set in the player, a query() for it + will return UNDEFINED. you CAN add 1 to an undefined to get 1. + + they just rang it one more time, so we'll take what was there and + add one. Then we'll put the new value back into the temp var + **see note at bottom of file. + */ + numrings=this_player()->GetProperty("rung_bell")+1; + this_player()->SetProperty("rung_bell",numrings); + write("DONG!\nYou ring a doorbell! Don't do it too many times!\n"); + say("DONG! A doorbell rings.\n"); + + if ( numrings>5 ) + { + if (!present("orc",this_object())) //nested if. see NOTE 2. + { + write("Now you've done it! An orc walks in a bonks you on the head.\n"); + say("Now " + this_player()->GetName() + " has done it! An orc walks in a bonks " + + objective(this_player()) + " on the head.\n"); + clone_object(ORC)->eventMove(this_object()); //this_object IS -this- room! + } + } + return 1; + } + + /* NOTE! + There are many ways to do the same thing with code. Some ways + are more readable. Some are less. Some are more efficient. + Some ways are very readable and only slightly less efficient. + I urge you to start out writing code that is readable AND correct, + rather then try to squeeze things down to one line of code. The + goal is to learn -- to understand what you're doing. If you + attempt to copy code that is all squeezed down into one line, and + you really don't understand it, then you'll be forever just copying + code and not really "getting it". + + That said. + in the add_action i did the following: + + int numrings; + numrings=this_player()->GetProperty("rung_bell")+1; + this_player()->SetProperty("rung_bell",numrings); + if ( numrings>5 ) + etc... + + I COULD have eliminated the variable numrings : + + this_player()->SetProperty("rung_bell", + this_player()->GetProperty("rung_bell") + 1); + if (this_player()->GetProperty("rung_bell") > 5) + etc... + + But, read both sets of code and determine for yourself which is easier + to read; easier to figure out on reading. You see, other people will + be reading your code. Other people will be debugging your code at + a later date. You may decide to never log on again and your project + is in a domain. The people in that domain will be fixing bugs & typos + & runtimes and you gotta bet that they will appreciate READABLE code... + as well as good comments. Never be afraid of comments! + + + NOTE 2! The nested if. Could also have been written: + if ( numrings>5 && ! present("orc",this_object())) + { + write("Now you've done it! An ord walks in a bonks you on the head.\n"); + say("Now " + this_player->GetName() + " has done it! An orc walks in a bonks " + + objective(this_player()) " + " on the head.\n"); + clone_object(ORC)->eventMove(this_object()); //this_object IS -this- room! + } + But, if you are having problems with the booleans && || and the code + is pretty clean & simple already, you might want to go the route + of nesting your if statements until you get the hang of && and ||. + */ diff -c -r --new-file ds2.0r26/lib/domains/examples/room/exroom6.c ds2.0r29/lib/domains/examples/room/exroom6.c *** ds2.0r26/lib/domains/examples/room/exroom6.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/exroom6.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,61 ---- + #include + #include "ex.h" + + #define SPIDER "/domains/town/npc/spider" + + inherit LIB_ROOM; + + int pre_north(); + + void create() + { + ::create(); + SetAmbientLight(30); + SetShort( "a room with a blocked exit" ); + SetLong(@EndText + There's not much here. Of course, we don't talk about + the spider in the long, cause it COULD be dead. + EndText + ); + SetExits( ([ + "south" : "/domains/examples/room/exroom5", + ]) ); + + AddExit("north", EXPATH + "exroom7", (: pre_north :)); + + SetInventory( ([ + SPIDER : 1, + ])); + } + + void init() + { + ::init(); + } + + /* In the pre_north() function, I am going to add a special treat! + If a creator is invisible, you can bypass the spider completely! + Woo! Woo! + */ + + int pre_north(string dir) + { + if( this_player()->GetInvis(1)) + return 1; + /* If the spider is present, the player can not go that way. We + are also checking to see if the spider is still alive since + we don't want a corpse to click menacingly. :) + If I were to only put if(present("spider")), then the dead + corpse would block the path and click menacingly. + By putting the if(living(present("spider", this_object()))) + we accomplish two checks on one line. Simple and elegant.*/ + if(present("spider", this_object()) && living(present("spider",this_object())) ) + { + write("The spider blocks your exit and clicks menacingly!\n"); + say("The spider blocks " + possessive_noun(this_player()->GetName()) + " exit and clicks menacingly!\n"); + return 0; + } + //if we get to here, the spider is not present, so we treat as a + //normal exit. ie: do nothing. return 1 allows the exit, if you remember. + return 1; + } diff -c -r --new-file ds2.0r26/lib/domains/examples/room/exroom7.c ds2.0r29/lib/domains/examples/room/exroom7.c *** ds2.0r26/lib/domains/examples/room/exroom7.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/exroom7.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,93 ---- + #include + #include "ex.h" + + inherit LIB_ROOM; + + int once; + int is_pulled(); + + void create() + { + ::create(); + SetAmbientLight(30); + SetShort( "two verbs for one action" ); + SetLong(@EndText + This room demonstrates how you can use two verbs to do + one thing. + There's a chain here. You can pull it or yank it. + + Note: See how we change the description of the chain? + It's important to remove 'quest hints' once a + quest has been done. And then put them back in + when the quest is ready to do. + EndText + ); + + // Here is another functional to point to the is_pulled() + // function. This is a very useful tool. + + SetItems( ([ + "chain" : (: is_pulled :), + ])); + + SetExits( ([ + "south" : EXPATH + "exroom6", + ])); + } + + /* Here you'll see that we have two add_actions. We have 'pull' and + 'yank'. If the player uses either verb when pulling the chain + the aa_chain() function is called. + */ + + void init() + { + ::init(); + add_action("aa_chain","pull"); + add_action("aa_chain","yank"); + } + + /* This is the first reset() function that we've seen so I'd like + to take a moment to explain it. The reset() function allows + an object to do self-maintenance. After every reset interval + (whose exact length is determined on a mud by mud basis, but + averages around every 2 hours), reset() is called in every + object that currently exists. Here, we use the reset() + function to return the variable 'once' back to 0 to allow the + chain to be pulled again after reset occurs. + */ + + void reset() + { + ::reset(); + once=0; + } + + /* query_verb() tells you what the player typed */ + mixed aa_chain (string str) + { + string averb=query_verb(); + if (str!="chain") + return notify_fail(capitalize(averb)+ " what?\n"); + if (once) + return notify_fail("The chain has already been " + + averb + "ed.\n"); + + // We're returning the averb variable that was defined and set + // above in a message to the player and the room. Then, we + // set the 'once' variable to show that the chain has been pulled. + write("You " + averb + " the chain!\n"); + say(this_player()->GetName() + " "+ averb + "s the chain!\n"); + once=1; + return 1; + } + + // This is the functional that was called to show the current state + // of the chain. Pulled or not pulled. + string is_pulled() + { + if( once ) + return "You see a plain chain.\n"; + else + return "Here's a chain begging to be yanked or pulled.\n"; + } diff -c -r --new-file ds2.0r26/lib/domains/examples/room/start.c ds2.0r29/lib/domains/examples/room/start.c *** ds2.0r26/lib/domains/examples/room/start.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/examples/room/start.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,20 ---- + #include + #include + #include "ex.h" + + inherit LIB_ROOM; + + + void create() { + room::create(); + SetAmbientLight(30); + SetShort("a blank room"); + SetLong("A featureless area. The example rooms are north."); + + SetExits( ([ + "north" : EXPATH + "entrance" + ]) ); + } + void init(){ + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/town/armor/badge.c ds2.0r29/lib/domains/town/armor/badge.c *** ds2.0r26/lib/domains/town/armor/badge.c Mon Nov 7 13:30:37 2005 --- ds2.0r29/lib/domains/town/armor/badge.c Sun Jul 9 22:06:36 2006 *************** *** 1,23 **** #include #include #include inherit LIB_ARMOR; static void create(){ armor::create(); SetKeyName("visitor pass"); ! SetId(({"testchar badge","badge","pass","visitor pass"})); SetShort("a test character Visitor's Pass"); SetLong("This clip-on plastic badge grants the wearer access to "+ "some areas typically restricted to creator staff only. Abuse of this "+ "pass is grounds for disciplinary action. A small scribble "+ "at the bottom of the pass reads: click heels"); SetMass(10); ! SetBaseCost("silver",5000); SetDamagePoints(100); SetArmorType(A_AMULET); SetRetainOnDeath(1); } void init(){ add_action("nplh","click"); } int nplh(string str){ --- 1,30 ---- #include + #include #include #include inherit LIB_ARMOR; + static void create(){ armor::create(); SetKeyName("visitor pass"); ! SetId(({"testchar badge","badge","pass","visitor's pass"})); SetShort("a test character Visitor's Pass"); SetLong("This clip-on plastic badge grants the wearer access to "+ "some areas typically restricted to creator staff only. Abuse of this "+ "pass is grounds for disciplinary action. A small scribble "+ "at the bottom of the pass reads: click heels"); + SetProperties(([ + "no steal" : 1, + ])); SetMass(10); ! SetBaseCost(5000); SetDamagePoints(100); SetArmorType(A_AMULET); SetRetainOnDeath(1); + SetRestrictLimbs( ({ "torso" }) ); } void init(){ + ::init(); add_action("nplh","click"); } int nplh(string str){ *************** *** 26,32 **** write("There's no place like home!\n"+ "You are transported by an awesome whirlwind somewhere "+ "else...\n"); ! this_player()->eventMoveLiving("/domains/town/room/road"); return 1; } write("You click your heels together...but feel "+ --- 33,39 ---- write("There's no place like home!\n"+ "You are transported by an awesome whirlwind somewhere "+ "else...\n"); ! this_player()->eventMoveLiving(ROOM_START); return 1; } write("You click your heels together...but feel "+ *************** *** 34,40 **** return 1; } } - string GetAffectLong(object ob) { if(!ob || !living(ob)) return 0; return ob->GetName() + " is an authorized Test Character."; --- 41,46 ---- diff -c -r --new-file ds2.0r26/lib/domains/town/npc/beggar.c ds2.0r29/lib/domains/town/npc/beggar.c *** ds2.0r26/lib/domains/town/npc/beggar.c Tue Mar 28 23:23:40 2006 --- ds2.0r29/lib/domains/town/npc/beggar.c Sun Jul 9 19:04:27 2006 *************** *** 1,4 **** --- 1,5 ---- #include + #include #include inherit LIB_SENTIENT; *************** *** 36,41 **** --- 37,44 ---- object map; if(present(ob->GetKeyName(),environment(this_object())) && !this_object()->GetInCombat() && + member_array(ob->GetRace(),RACES_D->GetRaces(1)) != -1 && + !creatorp(ob) && !stringp(ob->CanManipulate()) ){ eventForce("say here, you might need this"); eventForce("give my first map to "+ob->GetKeyName()); *************** *** 49,55 **** int SayHi(object ob){ if(present(ob->GetKeyName(),environment(this_object())) ! && !this_object()->GetInCombat()) eventForce("say Hi, "+this_player()->GetName()); return 1; } --- 52,59 ---- int SayHi(object ob){ if(present(ob->GetKeyName(),environment(this_object())) ! && !this_object()->GetInCombat() && ! member_array(ob->GetRace(),RACES_D->GetRaces(1)) != -1) eventForce("say Hi, "+this_player()->GetName()); return 1; } diff -c -r --new-file ds2.0r26/lib/domains/town/npc/bubb.c ds2.0r29/lib/domains/town/npc/bubb.c *** ds2.0r26/lib/domains/town/npc/bubb.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/town/npc/bubb.c Wed Jul 5 00:01:11 2006 *************** *** 0 **** --- 1,25 ---- + #include + + inherit LIB_TEACHER; + void create(){ + ::create(); + SetKeyName("bubb"); + SetId( ({"teacher","orc","schoolteacher","bubb the schoolteacher"}) ); + SetGender("male"); + SetRace("orc"); + SetNativeLanguage("english"); + SetTeachingFee(100); + SetLocalCurrency("silver"); + SetShort("Bubb the schoolteacher"); + SetLong("This is a person whose job it is to teach you things. "+ + "For example, 'ask teacher "+ + "to teach Tangetto' would prompt him to begin teaching a Tangetto "+ + "lesson to you, if he knows the language and you have "+ + "enough of his preferred currency. "); + SetLevel(1); + SetLanguage("Tangetto", 100); + AddTeachingLanguages( ({"Tangetto", "English" }) ); + } + void init() { + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/town/npc/bugg.c ds2.0r29/lib/domains/town/npc/bugg.c *** ds2.0r26/lib/domains/town/npc/bugg.c Wed Apr 5 19:44:08 2006 --- ds2.0r29/lib/domains/town/npc/bugg.c Wed Jul 5 00:01:11 2006 *************** *** 1,8 **** #include inherit LIB_TEACHER; void create(){ ! teacher::create(); SetKeyName("bugg"); SetId( ({"teacher","dwarf","schoolteacher","bugg the schoolteacher"}) ); SetGender("male"); --- 1,9 ---- #include inherit LIB_TEACHER; + void create(){ ! ::create(); SetKeyName("bugg"); SetId( ({"teacher","dwarf","schoolteacher","bugg the schoolteacher"}) ); SetGender("male"); diff -c -r --new-file ds2.0r26/lib/domains/town/npc/herkimer.c ds2.0r29/lib/domains/town/npc/herkimer.c *** ds2.0r26/lib/domains/town/npc/herkimer.c Sat Apr 22 15:14:41 2006 --- ds2.0r29/lib/domains/town/npc/herkimer.c Sat Jul 8 23:30:54 2006 *************** *** 34,40 **** "see right through you, but the smile from beneath "+ "his white beard is reassuring."); SetLevel(300); ! SetUnique(1); SetRace("human"); SetGender("male"); SetClass("mage"); --- 34,40 ---- "see right through you, but the smile from beneath "+ "his white beard is reassuring."); SetLevel(300); ! SetUnique(0); SetRace("human"); SetGender("male"); SetClass("mage"); diff -c -r --new-file ds2.0r26/lib/domains/town/npc/orc2.c ds2.0r29/lib/domains/town/npc/orc2.c *** ds2.0r26/lib/domains/town/npc/orc2.c Mon Nov 7 13:30:38 2005 --- ds2.0r29/lib/domains/town/npc/orc2.c Sun Jul 9 19:04:27 2006 *************** *** 2,7 **** --- 2,8 ---- inherit LIB_NPC; + int CheckOrc(mixed val){ if(!val) return 0; if(!objectp(val)) return 0; *************** *** 9,15 **** else eventForce("growl at "+val->GetKeyName()); return 1; } - static void create() { npc::create(); SetKeyName("orc"); --- 10,15 ---- *************** *** 30,32 **** --- 30,35 ---- ]) ); } + void init(){ + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/town/npc/otik.c ds2.0r29/lib/domains/town/npc/otik.c *** ds2.0r26/lib/domains/town/npc/otik.c Mon Nov 7 13:30:38 2005 --- ds2.0r29/lib/domains/town/npc/otik.c Wed Jul 5 00:01:11 2006 *************** *** 3,8 **** --- 3,9 ---- inherit LIB_VENDOR; + static void create() { ::create(); SetKeyName("otik"); *************** *** 25,27 **** --- 26,31 ---- SetSkill("bargaining", 1); } + void init(){ + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/town/npc/rat.c ds2.0r29/lib/domains/town/npc/rat.c *** ds2.0r26/lib/domains/town/npc/rat.c Mon May 22 11:34:51 2006 --- ds2.0r29/lib/domains/town/npc/rat.c Sat Jul 8 23:30:55 2006 *************** *** 9,20 **** SetId( ({"rat"}) ); SetShort("a rat"); SetLong("A scruffy little dirty rat."); - SetLevel(3); SetRace("rodent"); SetGender("male"); - SetClass("fighter"); - SetMaxHealthPoints(5); - SetWanderSpeed(1); SetEncounter(100); SetMessage("come","$N scurries in."); SetMessage("leave","$N scurries $D."); --- 9,18 ---- SetId( ({"rat"}) ); SetShort("a rat"); SetLong("A scruffy little dirty rat."); SetRace("rodent"); + SetHealthPoints(3); + SetMaxHealthPoints(3); SetGender("male"); SetEncounter(100); SetMessage("come","$N scurries in."); SetMessage("leave","$N scurries $D."); *************** *** 24,29 **** "You hear tiny munching sounds."})); } void init(){ - SetMaxHealthPoints(3); ::init(); } --- 22,26 ---- diff -c -r --new-file ds2.0r26/lib/domains/town/npc/thief.c ds2.0r29/lib/domains/town/npc/thief.c *** ds2.0r26/lib/domains/town/npc/thief.c Fri Mar 24 14:36:37 2006 --- ds2.0r29/lib/domains/town/npc/thief.c Sat Jul 8 23:30:55 2006 *************** *** 2,8 **** inherit LIB_NPC; - static void create() { npc::create(); SetKeyName("thief"); --- 2,7 ---- *************** *** 13,29 **** "is obviously a thief who has snuck into the "+ "mansion and taken up residence. You seem "+ "to have caught him just after his shower."); ! SetLevel(3); SetRace("human"); ! SetClass("fighter"); SetGender("male"); SetEncounter(100); ! SetMaxHealthPoints(100); SetInventory(([ "/domains/town/armor/towel":"wear towel", "/domains/town/weap/brush":"wield brush", "/domains/town/obj/safe_key":1, ]) ); } void init(){ ::init(); --- 12,29 ---- "is obviously a thief who has snuck into the "+ "mansion and taken up residence. You seem "+ "to have caught him just after his shower."); ! SetLevel(1); SetRace("human"); ! SetClass("thief"); SetGender("male"); SetEncounter(100); ! SetMaxHealthPoints(50); SetInventory(([ "/domains/town/armor/towel":"wear towel", "/domains/town/weap/brush":"wield brush", "/domains/town/obj/safe_key":1, ]) ); + SetHealthPoints(50); } void init(){ ::init(); diff -c -r --new-file ds2.0r26/lib/domains/town/npc/zoe.c ds2.0r29/lib/domains/town/npc/zoe.c *** ds2.0r26/lib/domains/town/npc/zoe.c Sun Jun 18 16:20:54 2006 --- ds2.0r29/lib/domains/town/npc/zoe.c Sat Jul 8 23:30:55 2006 *************** *** 3,8 **** --- 3,9 ---- inherit LIB_TELLER; + static void create() { ::create(); SetKeyName("zoe"); *************** *** 28,30 **** --- 29,34 ---- SetCurrencies( ({ "dollars", "copper", "silver", "electrum", "gold", "platinum" }) ); } + void init(){ + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/town/obj/donation_box.c ds2.0r29/lib/domains/town/obj/donation_box.c *** ds2.0r26/lib/domains/town/obj/donation_box.c Thu Jan 5 00:16:26 2006 --- ds2.0r29/lib/domains/town/obj/donation_box.c Wed Jul 5 00:01:11 2006 *************** *** 28,30 **** --- 28,34 ---- void init(){ ::init(); } + + mixed CanGet(){ + return "This is for the needy, you scum! Earn your keep!"; + } diff -c -r --new-file ds2.0r26/lib/domains/town/obj/ebutton1.c ds2.0r29/lib/domains/town/obj/ebutton1.c *** ds2.0r26/lib/domains/town/obj/ebutton1.c Mon Nov 7 13:30:38 2005 --- ds2.0r29/lib/domains/town/obj/ebutton1.c Fri Jul 7 19:41:41 2006 *************** *** 15,23 **** static void create() { dummy::create(); ! SetKeyName("button"); ! SetId(({"button","one","first","1" })); ! SetAdjectives("elevator","button","one","first","1"); SetShort("a button"); SetLong("It is a button that you could probably press. The numeral \"1\" " "is printed on it."); --- 15,23 ---- static void create() { dummy::create(); ! SetKeyName("button 1"); ! SetId("button","one","1"); ! SetAdjectives("elevator","button","one","1"); SetShort("a button"); SetLong("It is a button that you could probably press. The numeral \"1\" " "is printed on it."); diff -c -r --new-file ds2.0r26/lib/domains/town/obj/ebutton2.c ds2.0r29/lib/domains/town/obj/ebutton2.c *** ds2.0r26/lib/domains/town/obj/ebutton2.c Mon Nov 7 13:30:38 2005 --- ds2.0r29/lib/domains/town/obj/ebutton2.c Sat Jul 8 23:30:55 2006 *************** *** 15,23 **** static void create() { dummy::create(); ! SetKeyName("button"); ! SetId(({"button","two","second","B" })); ! SetAdjectives("elevator","button","basement","second","B"); SetShort("a button"); SetLong("It is a button that you could probably press. The letter \"B\" " "is printed on it."); --- 15,23 ---- static void create() { dummy::create(); ! SetKeyName("button b"); ! SetId("b","button","two","B", "button B"); ! SetAdjectives("b", "elevator","button","basement","B"); SetShort("a button"); SetLong("It is a button that you could probably press. The letter \"B\" " "is printed on it."); diff -c -r --new-file ds2.0r26/lib/domains/town/obj/pack.c ds2.0r29/lib/domains/town/obj/pack.c *** ds2.0r26/lib/domains/town/obj/pack.c Sat Apr 22 15:14:46 2006 --- ds2.0r29/lib/domains/town/obj/pack.c Sun Jul 9 19:04:27 2006 *************** *** 10,16 **** SetKeyName("backpack"); SetId(({"pack"})); SetAdjectives(({"leather","soft","brown"})); ! SetShort("a soft, brown leather backpack"); SetLong("This is a medium-sized backpack made of soft brown leather. "+ "It seems suitable for carrying books around, for the busy college student. "+ "It features wide, comfortable straps for convenient wear."); --- 10,16 ---- SetKeyName("backpack"); SetId(({"pack"})); SetAdjectives(({"leather","soft","brown"})); ! SetShort("a soft brown leather backpack"); SetLong("This is a medium-sized backpack made of soft brown leather. "+ "It seems suitable for carrying books around, for the busy college student. "+ "It features wide, comfortable straps for convenient wear."); diff -c -r --new-file ds2.0r26/lib/domains/town/obj/rayovac.c ds2.0r29/lib/domains/town/obj/rayovac.c *** ds2.0r26/lib/domains/town/obj/rayovac.c Fri Mar 24 14:36:38 2006 --- ds2.0r29/lib/domains/town/obj/rayovac.c Sun Jul 9 19:04:28 2006 *************** *** 2,14 **** #include inherit "/lib/flashlight"; - void create(){ ::create(); SetKeyName("flashlight"); ! SetId( ({"fl","flashlight","light","torch","flashlite"}) ); SetAdjectives( ({"plastic","small","cheap","rayovac","Rayovac"}) ); ! SetShort( "a small, plastic flashlight" ); SetLong("This is a cheap Rayovac brand flashlight."); SetMass(20); SetBaseCost("silver",10); --- 2,13 ---- #include inherit "/lib/flashlight"; void create(){ ::create(); SetKeyName("flashlight"); ! SetId( ({"fl","flashlight","light","torch","flashlite", "rayovac"}) ); SetAdjectives( ({"plastic","small","cheap","rayovac","Rayovac"}) ); ! SetShort("a small plastic flashlight"); SetLong("This is a cheap Rayovac brand flashlight."); SetMass(20); SetBaseCost("silver",10); diff -c -r --new-file ds2.0r26/lib/domains/town/obj/simple_chair.c ds2.0r29/lib/domains/town/obj/simple_chair.c *** ds2.0r26/lib/domains/town/obj/simple_chair.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/domains/town/obj/simple_chair.c Sun Jul 9 22:06:36 2006 *************** *** 0 **** --- 1,18 ---- + #include + + inherit LIB_CHAIR; + + static void create() { + chair::create(); + SetKeyName("chair"); + SetAdjectives( ({"simple", "wooden"}) ); + SetId("chair"); + SetShort("a wooden chair"); + SetLong("A simple chair, made of wood, for sitting on."); + SetMass(150); + SetDollarCost(15); + SetMaxSitters(1); + } + void init(){ + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/town/obj/table.c ds2.0r29/lib/domains/town/obj/table.c *** ds2.0r26/lib/domains/town/obj/table.c Thu Jan 5 00:16:26 2006 --- ds2.0r29/lib/domains/town/obj/table.c Sun Jul 9 22:06:36 2006 *************** *** 1,11 **** #include - inherit LIB_STORAGE; inherit LIB_CHAIR; ! inherit "/lib/comp/surface"; void create() { ! ::create(); SetKeyName("wooden table"); SetId( ({ "table" }) ); SetAdjectives( ({ "wood","wooden", "simple", "medium-sized" "medium sized" }) ); --- 1,11 ---- #include inherit LIB_CHAIR; ! inherit LIB_SURFACE; void create() { ! surface::create(); ! chair::create(); SetKeyName("wooden table"); SetId( ({ "table" }) ); SetAdjectives( ({ "wood","wooden", "simple", "medium-sized" "medium sized" }) ); diff -c -r --new-file ds2.0r26/lib/domains/town/obj/torch.c ds2.0r29/lib/domains/town/obj/torch.c *** ds2.0r26/lib/domains/town/obj/torch.c Mon Nov 7 13:30:38 2005 --- ds2.0r29/lib/domains/town/obj/torch.c Sun Jul 9 19:04:28 2006 *************** *** 7,13 **** SetKeyName("torch"); SetId( ({ "torch", "old torch", "wooden torch" }) ); SetAdjectives( ({ "old", "wooden" }) ); ! SetShort("an old, wooden torch"); SetLong("An old, wooden torch with a bit of cloth wrapped around " "one end and dipped into a flamable substance."); SetRadiantLight(7); --- 7,13 ---- SetKeyName("torch"); SetId( ({ "torch", "old torch", "wooden torch" }) ); SetAdjectives( ({ "old", "wooden" }) ); ! SetShort("an old wooden torch"); SetLong("An old, wooden torch with a bit of cloth wrapped around " "one end and dipped into a flamable substance."); SetRadiantLight(7); *************** *** 20,22 **** --- 20,25 ---- SetBurntValue(10); SetClass(10); } + void init(){ + ::init(); + } diff -c -r --new-file ds2.0r26/lib/domains/town/room/adv_guild.c ds2.0r29/lib/domains/town/room/adv_guild.c *** ds2.0r26/lib/domains/town/room/adv_guild.c Sun Jun 18 16:20:55 2006 --- ds2.0r29/lib/domains/town/room/adv_guild.c Sat Jul 8 23:30:55 2006 *************** *** 30,43 **** SetInventory(([ "/domains/town/obj/bin" : 1, "/domains/town/obj/table" : 1, ])); SetRead( ([ ({"list","scroll"}) : (: ReadScroll :), ({"instructions","sign"}) : (: ReadSign :) ]) ); - AddStuff( ({ "/domains/town/npc/dirk" - }) ); SetProperty("no attack", 1); ob = new("/lib/bboard"); ob->SetKeyName("chalkboard"); --- 30,42 ---- SetInventory(([ "/domains/town/obj/bin" : 1, "/domains/town/obj/table" : 1, + "/domains/town/npc/dirk" : 1 ])); SetRead( ([ ({"list","scroll"}) : (: ReadScroll :), ({"instructions","sign"}) : (: ReadSign :) ]) ); SetProperty("no attack", 1); ob = new("/lib/bboard"); ob->SetKeyName("chalkboard"); diff -c -r --new-file ds2.0r26/lib/domains/town/room/elevator.c ds2.0r29/lib/domains/town/room/elevator.c *** ds2.0r26/lib/domains/town/room/elevator.c Sun Dec 18 01:56:22 2005 --- ds2.0r29/lib/domains/town/room/elevator.c Sun Jul 9 22:06:36 2006 *************** *** 8,16 **** SetClimate("indoors"); SetAmbientLight(30); SetShort("Church Elevator"); ! SetLong("This is the elevator in the village church. The " ! "elevator door is on the east wall. Two buttons are " ! "set into the wall next to the door."); floor=1; moving = 0; closed=1; --- 8,14 ---- SetClimate("indoors"); SetAmbientLight(30); SetShort("Church Elevator"); ! SetLong("This is the elevator in the village church. The elevator door is on the east wall. Two buttons are set into the wall next to the door, labeled '1' and 'b'."); floor=1; moving = 0; closed=1; *************** *** 21,27 **** SetObviousExits("e"); SetItems(([ "elevator" : "A means of vertical indoors transportation.", ! "wall" : "The first and second buttons are on the wall.", ({"elevator door","door"}) : "The door to the outside." ]) ); --- 19,25 ---- SetObviousExits("e"); SetItems(([ "elevator" : "A means of vertical indoors transportation.", ! "wall" : "The buttons are on the wall.", ({"elevator door","door"}) : "The door to the outside." ]) ); *************** *** 71,84 **** return 1; } int CanReceive(object ob) { ! if(closed > 0){ message("info","The elevator door is closed.", ob); return 0; } return 1; } int CanRelease(object ob){ ! if(closed > 0 && !creatorp(ob)){ message("info","The elevator door is closed.", ob); return 0; } --- 69,88 ---- return 1; } int CanReceive(object ob) { ! //tc("verb: "+query_verb()); ! if(closed > 0 && query_verb() == "go"){ message("info","The elevator door is closed.", ob); return 0; } return 1; } int CanRelease(object ob){ ! if(archp(ob)) { ! tell_object(ob,"%^RED%^As archwizard, you are permitted to " ! "exit the elevator at any time. Normal creators and " ! "players cannot do this.%^RESET%^\n"); ! } ! if(closed > 0 && query_verb() == "go" ){ message("info","The elevator door is closed.", ob); return 0; } diff -c -r --new-file ds2.0r26/lib/domains/town/room/gate.c ds2.0r29/lib/domains/town/room/gate.c *** ds2.0r26/lib/domains/town/room/gate.c Wed May 24 12:05:36 2006 --- ds2.0r29/lib/domains/town/room/gate.c Sat Jul 8 23:30:56 2006 *************** *** 1,7 **** #include inherit LIB_ROOM; - int PreExit(){ if(this_player()->GetLevel() > 3 && !creatorp(this_player())){ if(present("gate guard",this_object())){ --- 1,6 ---- *************** *** 49,61 **** "casual entry. They are made of brick and appear old " "and strong.", ]) ); SetExits( ([ "north" : "/domains/town/room/road1", ]) ); AddExit("south", "/domains/town/room/mansion_ext", (: PreExit :)); - AddStuff( ({ - "/domains/town/npc/mp" - }) ); SetProperty("no attack", 1); } --- 48,60 ---- "casual entry. They are made of brick and appear old " "and strong.", ]) ); + SetInventory(([ + "/domains/town/npc/mp" : 1, + ])); SetExits( ([ "north" : "/domains/town/room/road1", ]) ); AddExit("south", "/domains/town/room/mansion_ext", (: PreExit :)); SetProperty("no attack", 1); } diff -c -r --new-file ds2.0r26/lib/domains/town/room/magic_guild.c ds2.0r29/lib/domains/town/room/magic_guild.c *** ds2.0r26/lib/domains/town/room/magic_guild.c Thu Jan 5 00:17:16 2006 --- ds2.0r29/lib/domains/town/room/magic_guild.c Sat Jul 8 23:30:56 2006 *************** *** 32,43 **** SetItems( ([ ({"list","list on the wall"}) : "A list of available spells", ]) ); SetRead(({"list","list on wall"}) , (: ReadList :) ); SetExits( ([ "north" : "/domains/town/room/magic_shop" ]) ); SetObviousExits("n"); - AddStuff( ({ "/domains/town/npc/herkimer" }) ); } void init(){ --- 32,45 ---- SetItems( ([ ({"list","list on the wall"}) : "A list of available spells", ]) ); + SetInventory(([ + "/domains/town/npc/herkimer" : 1, + ])); SetRead(({"list","list on wall"}) , (: ReadList :) ); SetExits( ([ "north" : "/domains/town/room/magic_shop" ]) ); SetObviousExits("n"); } void init(){ diff -c -r --new-file ds2.0r26/lib/domains/town/room/riverbank.c ds2.0r29/lib/domains/town/room/riverbank.c *** ds2.0r26/lib/domains/town/room/riverbank.c Fri May 12 21:14:30 2006 --- ds2.0r29/lib/domains/town/room/riverbank.c Wed Jul 5 00:01:11 2006 *************** *** 16,22 **** "no paralyze":0, "no teleport":0])); SetItems(([ "river" : "A swift moving river, probably quite deep." , ! ({"bank","riverbank","here"}) : "This is the edge of a powerful river."])); SetInventory(([ "/domains/town/npc/troll" : 1, "/domains/town/obj/rocks" : 1, --- 16,26 ---- "no paralyze":0, "no teleport":0])); SetItems(([ "river" : "A swift moving river, probably quite deep." , ! ({"bank","riverbank","here","water"}) : "This is the edge of a powerful river."])); ! SetListen(([ ! ({ "river", "water" }) : "You hear it rushing by.", ! "default" : "You can hear the roar of the river rushing by.", ! ])); SetInventory(([ "/domains/town/npc/troll" : 1, "/domains/town/obj/rocks" : 1, *************** *** 30,36 **** void init() { ::init(); SetSmell(([])); - SetListen(([ "default" : "You can hear the roar of the river rushing by."])); } int CanReceive(object ob){ --- 34,39 ---- diff -c -r --new-file ds2.0r26/lib/domains/town/room/road2.c ds2.0r29/lib/domains/town/room/road2.c *** ds2.0r26/lib/domains/town/room/road2.c Wed May 24 12:05:36 2006 --- ds2.0r29/lib/domains/town/room/road2.c Sat Jul 8 23:30:56 2006 *************** *** 1,21 **** #include inherit LIB_ROOM; static void create() { room::create(); SetClimate("outdoors"); SetAmbientLight(30); SetShort("West Village road"); ! SetLong("This is a well-traveled road, leading east into town and west away from it. An old, humpbacked bridge is west of here."); SetItems(([ ({ "fort", "fortress", "fortress in the distance" }) : "It can't be seen well from here, but far north is what appears to be a large fortress built on a high plateau.", ({ "road", "roads" }) : "This is a simple east-west road that goes east into town and west away from it. Another road, paved with cobblestones, intersects here to the north and leads high toward a fortress in the distance.", "cobblestone road" : "This is where a cobblestone road begins that is built on an steep incline and rises up as it leads north to a high plateau.", ])); ! SetExits( ([ "west" : "/domains/town/room/bridge", "east" : "/domains/town/room/road1", ]) ); } void init(){ --- 1,29 ---- #include inherit LIB_ROOM; + string LongDesc(){ + string desc = "This is a well-traveled road, leading east into town and west away from it. An old, humpbacked bridge is west of here."; + if(this_object()->GetExit("north")) + desc += " A road north leads up to a plateau where a fortress stands in the distance."; + return desc; + } + static void create() { room::create(); SetClimate("outdoors"); SetAmbientLight(30); SetShort("West Village road"); ! SetLong((: LongDesc :)); SetItems(([ ({ "fort", "fortress", "fortress in the distance" }) : "It can't be seen well from here, but far north is what appears to be a large fortress built on a high plateau.", ({ "road", "roads" }) : "This is a simple east-west road that goes east into town and west away from it. Another road, paved with cobblestones, intersects here to the north and leads high toward a fortress in the distance.", "cobblestone road" : "This is where a cobblestone road begins that is built on an steep incline and rises up as it leads north to a high plateau.", ])); ! SetExits( ([ "west" : "/domains/town/room/bridge", "east" : "/domains/town/room/road1", ]) ); + if(mud_name() == "Dead Souls") AddExit("north","/domains/fort/room/f_road4.c"); } void init(){ diff -c -r --new-file ds2.0r26/lib/domains/town/txt/hints_sign.txt ds2.0r29/lib/domains/town/txt/hints_sign.txt *** ds2.0r26/lib/domains/town/txt/hints_sign.txt Wed May 24 12:05:37 2006 --- ds2.0r29/lib/domains/town/txt/hints_sign.txt Wed Jul 5 00:01:12 2006 *************** *** 18,30 **** - If you want to know what is inside a container (like a bag or a box) you have to look *in* it. Example: look in bag - The wimpy command will make you automatically run away from combat when your health hits the percentage you specify. - - Anything you carry that isn't worn or wielded makes it almost - impossible to fight well. Get a backpack to keep your stuff in - while in combat. - - Armor is very important. Without it, it is very easy to lose life and limb. --- 18,34 ---- - If you want to know what is inside a container (like a bag or a box) you have to look *in* it. Example: look in bag + - It is almost imposible to fight well if you're carrying + stuff. Anything you carry that is not wielded or worn is a + major problem in combat, so wear a backpack to keep your stuff in. + + - If you don't have the "two-handed" or "two-weapon" combat + skills, you will fight very poorly when wielding multiple or + two-handed weapons. Generally only fighters train in these skills. + - The wimpy command will make you automatically run away from combat when your health hits the percentage you specify. - Armor is very important. Without it, it is very easy to lose life and limb. diff -c -r --new-file ds2.0r26/lib/domains/town/weap/carving_knife.c ds2.0r29/lib/domains/town/weap/carving_knife.c *** ds2.0r26/lib/domains/town/weap/carving_knife.c Wed Jan 11 23:09:54 2006 --- ds2.0r29/lib/domains/town/weap/carving_knife.c Wed Jul 5 00:01:12 2006 *************** *** 7,15 **** static void create() { item::create(); SetKeyName("carving knife"); SetId( ({ "knife"})); ! SetAdjectives( ({ "serrated","sharp","razor sharp","steel","hefty","stainless","carving"})); ! SetShort("a serrated, 8-inch carving knife"); SetLong("This is a serrated, 8-inch carving knife. This razor sharp "+ "knife has been forged from molded and hammered high-carbon "+ "stainless steel. It is solid, hefty, and well-balanced. "+ --- 7,15 ---- static void create() { item::create(); SetKeyName("carving knife"); + SetAdjectives( ({"8-inch", "serrated", "sharp", "razor-sharp", "razor", "steel", "hefty", "stainless", "carving"}) ); SetId( ({ "knife"})); ! SetShort("a serrated 8-inch carving knife"); SetLong("This is a serrated, 8-inch carving knife. This razor sharp "+ "knife has been forged from molded and hammered high-carbon "+ "stainless steel. It is solid, hefty, and well-balanced. "+ diff -c -r --new-file ds2.0r26/lib/lib/blank_pile.c ds2.0r29/lib/lib/blank_pile.c *** ds2.0r26/lib/lib/blank_pile.c Sat Apr 22 15:14:57 2006 --- ds2.0r29/lib/lib/blank_pile.c Fri Jul 7 19:41:41 2006 *************** *** 1,23 **** #include ! inherit LIB_ITEM; ! ! private string PileType = 0; ! int PileAmount = 0; static void create() { ! string *saveds; ! item::create(); ! saveds = item::GetSave(); ! saveds += ({ "PileType", "PileAmount" }); ! AddSave( saveds ); SetKeyName("money"); } string array GetId() { string array id; ! id = item::GetId(); if( PileType ) { if(PileType != "dollars") { id += ({ PileType, PileAmount + " " + PileType +" coins"}); --- 1,16 ---- #include ! inherit LIB_PILE; static void create() { ! pile::create(); SetKeyName("money"); } string array GetId() { string array id; ! id = pile::GetId(); if( PileType ) { if(PileType != "dollars") { id += ({ PileType, PileAmount + " " + PileType +" coins"}); *************** *** 30,59 **** } } - varargs string GetLong(string str) { - if( !PileAmount ) { - return 0; - } - if(PileType != "dollars") { - return PileAmount + " " + PileType + " coins."; - } - else return PileAmount + " " + PileType + "."; - } - - int GetMass() { - return currency_mass(PileAmount, PileType); - } - - void SetPile(string str, int amt) { - PileType = str; - PileAmount = amt; - parse_refresh(); - } - - string GetPileType() { return PileType; } - - int GetPileAmount() { return PileAmount; } - string GetShort() { string sum; if(!PileAmount) sum = "some"; --- 23,28 ---- *************** *** 64,130 **** else return sum + " " + PileType ; } - mixed eventGetCurrency(object who, int amount, string curr) { - string sum; - if(!amount) amount = PileAmount; - if( who->AddCurrency(curr, amount) == -1 ) { - who->eventPrint("You had a problem getting the money."); - return 1; - } - if(!amount) sum = "some"; - else sum = cardinal(amount); - send_messages("get", "$agent_name $agent_verb " + sum + " " + - curr + " " + GetShort() + ".", who, 0, environment(who)); - PileAmount -= amount; - if( PileAmount < 1 ) { - call_out((: Destruct :), 0); - return 1; - } - SetPile(PileType, PileAmount); /* This refreshes the parser */ - return 1; - } - - int eventMove(mixed dest) { - int x; - - x = item::eventMove(dest); - if( !environment() || !living(environment()) ) { - return x; - } - if(environment() && living(environment()) ) { - environment()->AddCurrency(PileType, PileAmount); - environment()->AddCarriedMass(-this_object()->GetMass()); - SetShort(PileAmount + " " + PileType); - //PileAmount = 0; - call_out((: Destruct :), 0); - return x; - } - } - - mixed direct_get_wrd_wrd_out_of_obj(string num, string curr) { - int amt; - - if( environment() != environment(this_player()) ) { - return "#You cannot reach the money!"; - } - if( num[0] < '0' || num[0] > '9' ) { - return 0; - } - if( (amt = to_int(num)) < 1 ) { - return "That's a totally bogus amount."; - } - if( curr != PileType ) { - return "#There are no " + curr + " there, only " + PileType + "."; - } - if( amt > PileAmount ) { - return "#There is not that much there."; - } - if( !this_player()->CanCarry(currency_mass(amt, curr)) ) { - return "It is too heavy for you!"; - } - return 1; - } - - mixed direct_get_wrd_wrd_from_obj(string amt, string curr) { - return direct_get_wrd_wrd_out_of_obj(amt, curr); - } --- 33,35 ---- diff -c -r --new-file ds2.0r26/lib/lib/body.c ds2.0r29/lib/lib/body.c *** ds2.0r26/lib/lib/body.c Sun Jun 18 18:00:26 2006 --- ds2.0r29/lib/lib/body.c Sun Jul 9 19:04:28 2006 *************** *** 9,14 **** --- 9,15 ---- #include #include + #include #include #include #include *************** *** 28,34 **** private int HealthPoints, MagicPoints, ExperiencePoints, QuestPoints; private int melee; ! private int Alcohol, Caffeine, Food, Drink, Poison, Sleeping; private float StaminaPoints; private string Torso, Biter; private mapping Fingers, Limbs, MissingLimbs; --- 29,35 ---- private int HealthPoints, MagicPoints, ExperiencePoints, QuestPoints; private int melee; ! private int Alcohol, Caffeine, Food, Drink, Poison, Sleeping, DeathEvents; private float StaminaPoints; private string Torso, Biter; private mapping Fingers, Limbs, MissingLimbs; *************** *** 51,57 **** PoliticalParty = "UNDECIDED"; rifleshot_wounds = 0; gunshot_wounds = 0; ! NewBody(0); Protect = 0; WornItems = ([]); --- 52,58 ---- PoliticalParty = "UNDECIDED"; rifleshot_wounds = 0; gunshot_wounds = 0; ! DeathEvents = 0; NewBody(0); Protect = 0; WornItems = ([]); *************** *** 68,83 **** ExtraChannels = ({}); } int GetEncumbrance(){ int encumbrance = 0; object *stuff = filter(all_inventory(this_object()), (: !($1->GetWorn()) :) ); - //tc("ENABLE_ENCUMBRANCE: "+ENABLE_ENCUMBRANCE,"cyan"); if(!(ENABLE_ENCUMBRANCE) || inherits(LIB_NPC,this_object()) ) return encumbrance; - //tc("bad encumbrance","red"); if(sizeof(stuff)) foreach(object item in stuff) ! encumbrance += item->GetMass(); ! if(sizeof(stuff)) encumbrance *= sizeof(stuff); return encumbrance; } --- 69,88 ---- ExtraChannels = ({}); } + varargs mixed eventBuy(mixed arg1, mixed arg2, mixed arg3){ + //This function will hopefully get overridden where appropriate. + write(capitalize(this_object()->GetShort())+" isn't buying anything from you."); + return 1; + } + int GetEncumbrance(){ int encumbrance = 0; object *stuff = filter(all_inventory(this_object()), (: !($1->GetWorn()) :) ); if(!(ENABLE_ENCUMBRANCE) || inherits(LIB_NPC,this_object()) ) return encumbrance; if(sizeof(stuff)) foreach(object item in stuff) ! encumbrance += (item->GetMass())/2; ! if(sizeof(stuff)) encumbrance += sizeof(stuff); return encumbrance; } *************** *** 200,206 **** int eventCollapse() { int position = GetPosition(); ! foreach(object ob in all_inventory(environment(this_player()))){ if(inherits(LIB_CHAIR,ob) || inherits(LIB_BED,ob) ){ ob->eventReleaseStand(this_object()); } --- 205,213 ---- int eventCollapse() { int position = GetPosition(); ! if(!this_object() || !environment()) return 0; ! ! foreach(object ob in all_inventory(environment())){ if(inherits(LIB_CHAIR,ob) || inherits(LIB_BED,ob) ){ ob->eventReleaseStand(this_object()); } *************** *** 606,615 **** --- 613,627 ---- varargs int eventDie(mixed agent) { int x; string killer, death_annc; + object crime_scene; //debug(identify(agent)); //tc("stack: "+identify(get_stack())); //if(!agent) agent = previous_object(); + + if(DeathEvents) return 1; + DeathEvents = 1; + if(agent && stringp(agent)) killer = agent + " "; else { //tc("previous: "+identify(previous_object(-1))); *************** *** 627,639 **** if( x ) agent->eventDestroyEnemy(this_object()); else agent->eventKillEnemy(this_object()); } ! if( environment() ) { object *obs; string *currs; object ob; string curr; int i; if(GetRace() == "golem") { ob = new(LIB_CLAY); if(GetBodyComposition()) ob->SetComposition(GetBodyComposition()); --- 639,655 ---- if( x ) agent->eventDestroyEnemy(this_object()); else agent->eventKillEnemy(this_object()); } ! crime_scene = environment(); ! if( crime_scene ) { object *obs; string *currs; object ob; string curr; int i; + //I'd like to move the living body out first, but for now this + //misfeature stays. + //this_object()->eventMove(ROOM_VOID); if(GetRace() == "golem") { ob = new(LIB_CLAY); if(GetBodyComposition()) ob->SetComposition(GetBodyComposition()); *************** *** 643,649 **** else ob = new(LIB_CORPSE); ob->SetCorpse(this_object()); } ! ob->eventMove(environment()); obs = filter(all_inventory(), (: !((int)$1->GetRetainOnDeath()) :)); i = sizeof(obs); obs->eventMove(ob); --- 659,665 ---- else ob = new(LIB_CORPSE); ob->SetCorpse(this_object()); } ! ob->eventMove(crime_scene); obs = filter(all_inventory(), (: !((int)$1->GetRetainOnDeath()) :)); i = sizeof(obs); obs->eventMove(ob); *************** *** 665,670 **** --- 681,687 ---- //call_out( function() { Dying = 0; }, 0); evaluate( function() { Dying = 0; }); + flush_messages(); return 1; } *************** *** 1099,1105 **** string limbname,adjname,templimbname; int i; ! if(limb == "torso") return 0; if( sscanf(limb, "%s %s", adjname, templimbname) == 2 ) limbname=templimbname; else limbname=limb; --- 1116,1122 ---- string limbname,adjname,templimbname; int i; ! if(limb == "torso" || limb == "neck") return 0; if( sscanf(limb, "%s %s", adjname, templimbname) == 2 ) limbname=templimbname; else limbname=limb; *************** *** 1702,1704 **** --- 1719,1731 ---- } + int GetDeathEvents(){ + return DeathEvents; + } + + int SetDeathEvents(int i){ + if(!i) DeathEvents = 0; + else DeathEvents = 1; + return DeathEvents; + } + diff -c -r --new-file ds2.0r26/lib/lib/combat.c ds2.0r29/lib/lib/combat.c *** ds2.0r26/lib/lib/combat.c Sun Jun 18 16:20:56 2006 --- ds2.0r29/lib/lib/combat.c Sat Jul 8 23:30:57 2006 *************** *** 18,24 **** inherit LIB_CLASSES; inherit LIB_COMBATMSG; ! private int Wimpy; private string WimpyCommand; private static int cParalyzed, tNextRound; private static string TargetLimb, Party; --- 18,24 ---- inherit LIB_CLASSES; inherit LIB_COMBATMSG; ! private int Wimpy, Dead; private string WimpyCommand; private static int cParalyzed, tNextRound; private static string TargetLimb, Party; *************** *** 57,62 **** --- 57,76 ---- } /* ***************** /lib/combat.c data functions ***************** */ + varargs int GetMaxHealthPoints(string limb){ + return race::GetMaxHealthPoints(limb); + } + + int GetDead(){ + return Dead; + } + + int SetDead(int i){ + if(!i) Dead = 0; + else Dead = 1; + return Dead; + } + object array GetEnemies() { return Enemies; } *************** *** 474,479 **** --- 488,496 ---- object ob; int x; + if(Dead) return 1; + Dead = 1; + x = race::eventDie(agent); if( x != 1 ) { return x; *************** *** 485,490 **** --- 502,508 ---- } environment()->eventLivingDied(this_object(), agent); Enemies = ({}); + flush_messages(); return 1; } *************** *** 494,499 **** --- 512,520 ---- int type = tNextRound; int position = GetPosition(); + if(Dead) return 1; + if(target->GetDead()) return 1; + fNextRound = 0; tNextRound = ROUND_UNDEFINED; if( position == POSITION_LYING || position == POSITION_SITTING && *************** *** 569,574 **** --- 590,598 ---- object array weapons = 0; function f = 0; + if(Dead) return 1; + if(target->GetDead()) return 1; + if( arrayp(val) ) { weapons = val; } *************** *** 601,606 **** --- 625,633 ---- int bonus = GetCombatBonus(level); int power, pro, con; + if(Dead) return; + if(target->GetDead()) return; + if( target->GetDying() ) { return; } *************** *** 633,641 **** int damage_type, damage, weapon_damage, actual_damage, encumbrance; encumbrance = this_object()->GetEncumbrance(); //tc("encumbrance: "+encumbrance,"white"); ! if(encumbrance > 30){ //tc("feep","yellow"); ! tell_object(this_object(),"You struggle to fight while heavily encumbered."); } eventTrainSkill(weapon_type + " attack", pro*2, con, 1, bonus); damage_type = weapon->GetDamageType(); --- 660,668 ---- int damage_type, damage, weapon_damage, actual_damage, encumbrance; encumbrance = this_object()->GetEncumbrance(); //tc("encumbrance: "+encumbrance,"white"); ! if(encumbrance > 20){ //tc("feep","yellow"); ! tell_object(this_object(),"You struggle to fight while carrying stuff."); } eventTrainSkill(weapon_type + " attack", pro*2, con, 1, bonus); damage_type = weapon->GetDamageType(); *************** *** 673,678 **** --- 700,708 ---- int count = sizeof(limbs); int attacks; + if(Dead) return 1; + if(target->GetDead()) return 1; + if( count < 2 ) { if(RACES_D->GetLimblessCombatRace(this_object()->GetRace())){ limbs = GetLimbs(); *************** *** 699,705 **** int pro, con; int chance; ! if( target->GetDying() ) { return; } --- 729,735 ---- int pro, con; int chance; ! if( target->GetDead() || Dead || target->GetDying() ) { return; } *************** *** 726,734 **** int x, encumbrance; encumbrance = this_object()->GetEncumbrance(); //tc("encumbrance: "+encumbrance,"white"); ! if(encumbrance > 30){ //tc("feep","blue"); ! tell_object(this_object(),"You struggle to fight while heavily encumbered."); } // I hit, how hard? eventTrainSkill("melee attack", pro, con, 1, --- 756,764 ---- int x, encumbrance; encumbrance = this_object()->GetEncumbrance(); //tc("encumbrance: "+encumbrance,"white"); ! if(encumbrance > 20){ //tc("feep","blue"); ! tell_object(this_object(),"You struggle to fight while carrying stuff."); } // I hit, how hard? eventTrainSkill("melee attack", pro, con, 1, *************** *** 755,760 **** --- 785,791 ---- } int eventMagicRound(mixed target, function f) { + if(target->GetDead()) return 1; evaluate(f, target); return target->GetDying(); } *************** *** 764,769 **** --- 795,802 ---- int con = target->GetDefenseChance(target->GetSkillLevel("melee defense")); int x = random(pro); + if(target->GetDead()) return 1; + if( environment() != environment(target) ) { eventPrint(target->GetName() + " has gone away."); return 1; *************** *** 839,844 **** --- 872,879 ---- varargs int eventReceiveAttack(int speed, string def, object agent) { int x, pro, level, bonus; + if(Dead) return 0; + if( !agent ) { agent = previous_object(); } *************** *** 919,926 **** mixed limbs) { int hp,encumbrance; encumbrance = this_object()->GetEncumbrance(); //tc("encumbrance: "+encumbrance,"white"); ! if(encumbrance > 30){ //tc("feep","green"); if(GetInCombat()) tell_object(this_object(),"You try to dodge while weighed down."); } --- 954,963 ---- mixed limbs) { int hp,encumbrance; encumbrance = this_object()->GetEncumbrance(); + + if(Dead) return 0; //tc("encumbrance: "+encumbrance,"white"); ! if(encumbrance > 200){ //tc("feep","green"); if(GetInCombat()) tell_object(this_object(),"You try to dodge while weighed down."); } diff -c -r --new-file ds2.0r26/lib/lib/combatmsg.c ds2.0r29/lib/lib/combatmsg.c *** ds2.0r26/lib/lib/combatmsg.c Mon Jan 16 23:03:04 2006 --- ds2.0r29/lib/lib/combatmsg.c Wed Jul 5 00:00:58 2006 *************** *** 9,14 **** --- 9,17 ---- static mixed GetMissData(object targ, int type, string limb) { string targ_name = (string)targ->GetName(); + + if(targ->GetDead() || this_object()->GetDead()) return 0; + if( type == -2 ) switch( random(7) ) { case 0: return ({ "%s completely %s %s.", *************** *** 91,96 **** --- 94,101 ---- static void eventSendMissMessages(object target, int x, string limb) { mixed data; + + if(target->GetDead() || this_object()->GetDead()) return; if( !limb ) limb = "body"; data = GetMissData(target, x, limb); if( sizeof(data) != 4 ) return; *************** *** 137,142 **** --- 142,149 ---- int i; string adverb; mixed verb, ptr, moves; + + if(target->GetDead() || this_object()->GetDead()) return; if( x < 0 ) { eventSendMissMessages(target, x, limb); return; *************** *** 167,172 **** --- 174,181 ---- int i; string adverb, type, weap; mixed verb, ptr, moves; + + if(target->GetDead() || this_object()->GetDead()) return; if( x < 0 ) { eventSendMissMessages(target, x, limb); return; diff -c -r --new-file ds2.0r26/lib/lib/command.c ds2.0r29/lib/lib/command.c *** ds2.0r26/lib/lib/command.c Sun Jun 18 16:20:56 2006 --- ds2.0r29/lib/lib/command.c Sun Jul 9 19:04:28 2006 *************** *** 18,23 **** --- 18,27 ---- private static string *SearchPath; private static string *apostrophe_exceptions; + int direct_force_liv_str() { return 1; } + int direct_force_liv_to_str() { return 1; } + + /* *************** /lib/command.c driver applies *************** */ static void create() { *************** *** 31,37 **** } static string process_input(string cmd) { - //tc(this_object()->GetName()+": "+identify(parse_command(cmd))); return cmd; } --- 35,40 ---- *************** *** 42,59 **** mixed err; string verb, file; - //if(ParseMe(args) == 1) return 1; - //tc(this_object()->GetName()+" parse_command_id_list(): "+identify(parse_command_id_list())); - //tc(this_object()->GetName()+" parse_command_plural_id_list(): "+identify(parse_command_plural_id_list())); - //tc(this_object()->GetName()+" parse_command_adjectiv_id_list(): "+identify(parse_command_adjectiv_id_list())); - //tc(this_object()->GetName()+" parse_command_prepos_list(): "+identify(parse_command_prepos_list())); - - if(sizeof(args) && member_array(query_verb(), apostrophe_exceptions) == -1) - args = replace_string(args,"'",""); - old_agent = this_agent(this_object()); verb = query_verb(); - //write("verb: "+verb); if(this_player()->GetSleeping() > 0) { if(verb != "wake") { --- 45,52 ---- *************** *** 76,129 **** if( (int)this_object()->GetProperty("parse debug") ) dbg = 1; if( (int)this_object()->GetProperty("debug") ) dbg = 1; else dbg = 0; - //tc("command: checkpoint 1","green"); if( (err = parse_sentence(cmd, dbg)) == 1 ) { this_agent(old_agent || 1); return 1; } - //tc("command: checkpoint 2","green"); if( err ) { - //tc("command: checkpoint 3. err: "+err,"green"); if( err == -1 ) { - //tc("command: checkpoint 4","green"); if( !(err = (string)VERBS_D->GetErrorMessage(verb)) && !(err = (string)SOUL_D->GetErrorMessage(verb)) ) { err = "Such a command exists, but no default " "syntax is known."; } } - //tc("command: checkpoint 5","green"); if( intp(err) ) /* MudOS bug */ err = "What?"; SetCommandFail(err); } - //tc("command: checkpoint 6","green"); message("error", GetCommandFail(), this_object()); this_agent(old_agent || 1); return 1; } - //tc("command: checkpoint 7","green"); } - //tc("command: checkpoint 8","green"); if( (err = (mixed)call_other(file, "cmd", args)) != 1 ) { string cmd; - //tc("command: checkpoint 9","green"); if( err ) SetCommandFail(err); if( !args || args == "" ) cmd = verb; else cmd = verb + " " + args; if( (err = parse_sentence(cmd)) == 1 ) { - //tc("command: checkpoint 10","green"); this_agent(old_agent || 1); return 1; } - //tc("command: checkpoint 11","green"); if( !err ) err = GetCommandFail(); message("error", err, this_object()); this_agent(old_agent || 1); return 1; } - //tc("command: checkpoint 12","green"); this_agent(old_agent || 1); return 1; } --- 69,110 ---- diff -c -r --new-file ds2.0r26/lib/lib/events/get_from.c ds2.0r29/lib/lib/events/get_from.c *** ds2.0r26/lib/lib/events/get_from.c Wed Feb 22 15:32:57 2006 --- ds2.0r29/lib/lib/events/get_from.c Sun Jul 9 19:04:28 2006 *************** *** 6,39 **** * Last modified: 96/12/22 */ // abstract methods int AddCarriedMass(int amount); string GetShort(); // end abstract methods mixed CanGetFrom(object who, object item) { - //tc("hit CanGetFrom"); - //tc("who: "+identify(who)); - //tc("item: "+identify(item)); - //tc("this_object: "+this_object()->GetName()); if( !item ) { - //tc("no item. about to return 0"); return 0; } if( environment(item) != this_object() ) { - //tc("this item isnt in my inventory. returning 0"); return 0; } - // if( environment(item) != this_object() ) { - ////tc("stack: "+get_stack()); - //tc("previous: "+identify(previous_object(-1))); - // - // return "#You can't do that."; - // } - //tc("survicved test"); if( environment(item) != this_object() ) { - //tc("oddness"); item = present(item->GetKeyName(),this_object()); if(!item) return 0; } --- 6,27 ---- * Last modified: 96/12/22 */ + #include + // abstract methods int AddCarriedMass(int amount); string GetShort(); // end abstract methods mixed CanGetFrom(object who, object item) { if( !item ) { return 0; } if( environment(item) != this_object() ) { return 0; } if( environment(item) != this_object() ) { item = present(item->GetKeyName(),this_object()); if(!item) return 0; } *************** *** 48,53 **** --- 36,47 ---- mixed CanPutInto(object who, object item) { object env; + if((inherits(LIB_SIT,item) && sizeof(item->GetSitters())) || + (inherits(LIB_LIE,item) && sizeof(item->GetLiers()))){ + write("There appears to be someone in your way."); + return 0; + } + if( item == this_object() ) { return "#You cannot change the laws of physics."; } *************** *** 65,71 **** mixed CanPutOnto(object who, object item) { object env; ! if(!inherits( "/lib/comp/surface", item ) ){ return "#That isn't a load-bearing surface."; } if( item == this_object() ) { --- 59,71 ---- mixed CanPutOnto(object who, object item) { object env; ! if((inherits(LIB_SIT,item) && sizeof(item->GetSitters())) || ! (inherits(LIB_LIE,item) && sizeof(item->GetLiers()))){ ! write("There appears to be someone preventing your access."); ! return 0; ! } ! ! if(!inherits( LIB_SURFACE, item ) ){ return "#That isn't a load-bearing surface."; } if( item == this_object() ) { *************** *** 86,92 **** string msg; int i, maxi; ! //tc("hit eventGetFrom. item is: " +identify(what),"red"); foreach(object ob in what ) { if( environment(ob) != this_object() ) { continue; --- 86,97 ---- string msg; int i, maxi; ! if((inherits(LIB_SIT,this_object()) && sizeof(this_object()->GetSitters())) || ! (inherits(LIB_LIE,this_object()) && sizeof(this_object()->GetLiers()))){ ! write("There appears to be someone on there."); ! return 0; ! } ! foreach(object ob in what ) { if( environment(ob) != this_object() ) { continue; *************** *** 138,143 **** --- 143,153 ---- } mixed eventPutOnto(object who, object what) { + if((inherits(LIB_SIT,this_object()) && sizeof(this_object()->GetSitters())) || + (inherits(LIB_LIE,this_object()) && sizeof(this_object()->GetLiers()))){ + write("There appears to be someone in the way of that."); + return 0; + } return what->eventPut(who, this_object()," onto "); } *************** *** 151,174 **** } mixed indirect_get_obj_from_obj(object item, object container) { - //tc("stack: "+get_stack()); - //tc("item is: " +identify(item)); - //tc("container is: " +identify(container)); - //tc("this object is: "+identify(this_object())); - //if(item) tc("item's environment is: "+identify(environment(item))); if(!item){ - //write("That's not there."); return 0; } if(environment(item) != this_object()) return 0; - // if(!(environment(item) == this_object())){ - // item = present(item->GetKeyName(),this_object()); - //tc("item is now: " +identify(item)); - //return 0; - // } - //tc("about to return CanGetFrom"); return CanGetFrom(this_player(), item); } --- 161,172 ---- diff -c -r --new-file ds2.0r26/lib/lib/events/lie.c ds2.0r29/lib/lib/events/lie.c *** ds2.0r26/lib/lib/events/lie.c Sun Dec 11 21:15:29 2005 --- ds2.0r29/lib/lib/events/lie.c Sun Jul 9 22:06:37 2006 *************** *** 1,4 **** --- 1,6 ---- #include + #include + inherit LIB_SIT; private int MaxLiers = 1; private object array Liers = ({}); *************** *** 12,27 **** } object array GetLiers() { ! return Liers; } mixed eventReceiveLay(object who) { Liers = ({ Liers..., who }); return 1; } mixed eventReleaseStand(object who) { Liers -= ({ who }); return 1; } --- 14,37 ---- } object array GetLiers() { ! return copy(Liers); } mixed eventReceiveLay(object who) { + if(who->GetProperty("furniture")){ + write("You are already using a piece of furniture."); + return 1; + } Liers = ({ Liers..., who }); + who->SetProperty("furniture", " on "+this_object()->GetShort()); + who->SetProperty("furniture_object", this_object()); return 1; } mixed eventReleaseStand(object who) { Liers -= ({ who }); + Liers = filter(Liers, (: objectp($1) :) ); + sit::eventReleaseStand(who); return 1; } *************** *** 39,41 **** --- 49,65 ---- mixed direct_lie_down_word_obj() { return direct_lie_word_obj(); } + + int CanGet(object who){ + object *liers = this_object()->GetLiers(); if(sizeof(liers)){ + foreach(object wer in liers){ if(!wer || environment(wer) != environment()) this_object()->eventReleaseStand(wer); + } + if(sizeof(this_object()->GetLiers())){ + write(this_object()->GetLiers()[0]->GetName()+" is using it right now."); + return 0; + } + else return sit::CanGet(who); + } + else return sit::CanGet(who); + } + diff -c -r --new-file ds2.0r26/lib/lib/events/look.c ds2.0r29/lib/lib/events/look.c *** ds2.0r26/lib/lib/events/look.c Fri May 12 21:15:17 2006 --- ds2.0r29/lib/lib/events/look.c Sun Jul 9 20:32:28 2006 *************** *** 8,13 **** --- 8,14 ---- #include #include + #include private mixed ExternalDesc = 0; private int Invisible = 0; *************** *** 173,188 **** GetShort() + ".", ({ who, this_object() })); } - if(inherits(LIB_SURFACE,this_object()) || - this_object()->GetOpacity() < 33){ - //tempdesc = this_object()->eventShowInterior(who); - who->eventPrint(desc); - this_object()->eventShowInterior(who); - } ! else { ! who->eventPrint(desc); } return 1; } --- 174,190 ---- GetShort() + ".", ({ who, this_object() })); } ! if((!inherits(LIB_SIT,this_object()) && !inherits(LIB_LIE,this_object())) || ! (!sizeof(this_object()->GetLiers()) && !sizeof(this_object()->GetSitters()))){ ! if(inherits(LIB_SURFACE,this_object()) || ! this_object()->GetOpacity() < 33){ ! who->eventPrint(desc); ! this_object()->eventShowInterior(who); ! } ! else who->eventPrint(desc); } + else who->eventPrint(desc); return 1; } *************** *** 204,210 **** --- 206,226 ---- } mixed direct_look_at_str_on_obj(string str, object target) { + object dingus; str = remove_article(lower_case(str)); + + if((inherits(LIB_SIT,target) && sizeof(target->GetSitters())) || + (inherits(LIB_LIE,target) && sizeof(target->GetLiers()))){ + write("There appears to be someone blocking your view."); + return 0; + } + + if((inherits(LIB_SURFACE,target) || living(target)) && dingus = present(str, target)){ + if(this_player()->GetEffectiveVision() == VISION_CLEAR){ + return dingus->GetExternalDesc(); + } + else return "#You can't quite make out its details."; + } if( !Items[str] ) { return "#There is no " + str + " on " + GetShort() + "."; } diff -c -r --new-file ds2.0r26/lib/lib/events/put.c ds2.0r29/lib/lib/events/put.c *** ds2.0r26/lib/lib/events/put.c Thu Apr 13 21:03:52 2006 --- ds2.0r29/lib/lib/events/put.c Sun Jul 9 19:04:28 2006 *************** *** 4,9 **** --- 4,11 ---- * created by Descartes of Borg 960114 */ + #include + private mixed PreventPut; // abstract methods *************** *** 51,68 **** varargs mixed eventPut(object who, object storage, string prep) { int depth; - if(!prep || prep == "") prep = " into "; ! if(prep == " onto " && !inherits( "/lib/comp/surface", previous_object() ) ) { who->eventPrint("That isn't a load-bearing surface."); return 0; } ! if(prep == " into " && inherits( "/lib/comp/surface", previous_object() ) ) { who->eventPrint("That's a surface. Try \"put on\""); return 0; } if( !eventMove(storage) ) { who->eventPrint("There is not enough room in there!"); return 0; --- 53,76 ---- varargs mixed eventPut(object who, object storage, string prep) { int depth; if(!prep || prep == "") prep = " into "; ! if(prep == " onto " && !inherits( LIB_SURFACE, previous_object() ) ) { who->eventPrint("That isn't a load-bearing surface."); return 0; } ! if(prep == " into " && inherits( LIB_SURFACE, previous_object() ) ) { who->eventPrint("That's a surface. Try \"put on\""); return 0; } + if((inherits(LIB_SIT,storage) && sizeof(storage->GetSitters())) || + (inherits(LIB_LIE,storage) && sizeof(storage->GetLiers()))){ + write("There appears to be someone blocking your access."); + return 0; + } + + if( !eventMove(storage) ) { who->eventPrint("There is not enough room in there!"); return 0; diff -c -r --new-file ds2.0r26/lib/lib/events/read.c ds2.0r29/lib/lib/events/read.c *** ds2.0r26/lib/lib/events/read.c Sat Mar 11 11:16:11 2006 --- ds2.0r29/lib/lib/events/read.c Wed Jul 5 00:01:05 2006 *************** *** 96,101 **** --- 96,102 ---- mixed ret; mixed val = GetRead(str); + //tc("-1"); if( arrayp(val) ) { val = val[query_night()]; } *************** *** 104,109 **** --- 105,111 ---- if( functionp(val) ) { if( functionp(val) & FP_OWNER_DESTED ) { who->eventPrint("There was a problem with the read."); + //tc("alpha"); return 1; } //The funtion being evaluated, GetRead, only takes one arg. *************** *** 111,116 **** --- 113,119 ---- ret = evaluate(val, str); if(!stringp(ret)) return 1; } + //tc("bravo"); environment(who)->eventPrint(who->GetName() + " reads " + GetShort() + ".", who); if(ret) val = ret; *************** *** 118,145 **** who->eventPrint("There is nothing to read."); return 1; } tmpfile = generate_tmp(); globalwho = who; globalval = val; if(Language){ write("The language appears to be "+capitalize(Language)+"."); } if(!globalval){ write("You can't read that."); return 0; } ! unguarded( (: write_file(tmpfile, globalval) :) ); ! if(Language && this_player()->GetLanguageLevel(Language) < 100){ if(sizeof(globalval) > 4800){ globalval = "It is too long and you are too unfamiliar with the language to make sense of it."; } ! else globalval = translate(val, this_player()->GetLanguageLevel(Language)); ! unguarded( (: write_file(tmpfile, globalval,1) :) ); } unguarded( (: globalwho->eventPage(tmpfile) :) ); unguarded( (: rm(tmpfile) :) ); return 1; --- 121,168 ---- who->eventPrint("There is nothing to read."); return 1; } + //tc("charlie"); tmpfile = generate_tmp(); + //tc("tmpfile: "+tmpfile); globalwho = who; globalval = val; + //tc("delta"); if(Language){ + //tc("echo"); write("The language appears to be "+capitalize(Language)+"."); } if(!globalval){ + //tc("foxtrot"); write("You can't read that."); return 0; } + //tc("0"); ! //unguarded( (: write_file(tmpfile, globalval) :) ); ! if(Language && (this_player()->GetLanguageLevel(Language) < 100 && ! !(this_player()->GetPolyglot()))){ ! //tc("1"); if(sizeof(globalval) > 4800){ + //tc("2"); globalval = "It is too long and you are too unfamiliar with the language to make sense of it."; } ! else { ! //tc("3"); ! globalval = translate(val, this_player()->GetLanguageLevel(Language)); ! } ! //tc("4"); ! } ! else { ! //tc("6"); ! globalval = val; } + //tc("val: "+val); + //tc("globalval: "+globalval); + unguarded( (: write_file(tmpfile, globalval,1) :) ); + unguarded( (: globalwho->eventPage(tmpfile) :) ); unguarded( (: rm(tmpfile) :) ); return 1; diff -c -r --new-file ds2.0r26/lib/lib/events/sit.c ds2.0r29/lib/lib/events/sit.c *** ds2.0r26/lib/lib/events/sit.c Sun Dec 11 21:15:29 2005 --- ds2.0r29/lib/lib/events/sit.c Sun Jul 9 22:06:37 2006 *************** *** 20,35 **** } object array GetSitters() { ! return Sitters; } mixed eventReceiveSit(object who) { Sitters = ({ Sitters..., who }); return 1; } mixed eventReleaseStand(object who) { Sitters -= ({ who }); return 1; } --- 20,44 ---- } object array GetSitters() { ! return copy(Sitters); } mixed eventReceiveSit(object who) { + if(who->GetProperty("furniture")){ + write("You are already using a piece of furniture."); + return 1; + } Sitters = ({ Sitters..., who }); + who->SetProperty("furniture", " on "+this_object()->GetShort()); + who->SetProperty("furniture_object", this_object()); return 1; } mixed eventReleaseStand(object who) { Sitters -= ({ who }); + Sitters = filter(Sitters, (: objectp($1) :) ); + if(who) who->RemoveProperty("furniture"); + if(who) who->RemoveProperty("furniture_object"); return 1; } *************** *** 47,49 **** --- 56,73 ---- mixed direct_sit_down_word_obj() { return direct_sit_word_obj(); } + + int CanGet(object who){ + object *sitters = this_object()->GetSitters(); + if(sizeof(sitters)){ + foreach(object wer in sitters){ + if(!wer || environment(wer) != environment()) this_object()->eventReleaseStand(wer); + } if(sizeof(this_object()->GetSitters())){ + write(this_object()->GetSitters()[0]->GetName()+" is using it right now."); + return 0; + } + else return 1; + } + else return 1; + } + diff -c -r --new-file ds2.0r26/lib/lib/exits.c ds2.0r29/lib/lib/exits.c *** ds2.0r26/lib/lib/exits.c Sun Jun 18 16:20:56 2006 --- ds2.0r29/lib/lib/exits.c Fri Jul 7 19:41:42 2006 *************** *** 67,75 **** return 1; } ! string GetDoor(string dir) { if(sizeof(Doors)) return Doors[dir]; ! else return ""; } string array GetDoors() { --- 67,75 ---- return 1; } ! mixed GetDoor(string dir) { if(sizeof(Doors)) return Doors[dir]; ! else return 0; } string array GetDoors() { *************** *** 82,87 **** --- 82,91 ---- if( ob ) { ob->SetDoor(file); } + + if(!file_exists(file) && !file_exists(file+".c")){ + return "Door not found."; + } file->eventRegisterSide(dir); return (Doors[dir] = file); } diff -c -r --new-file ds2.0r26/lib/lib/include/exits.h ds2.0r29/lib/lib/include/exits.h *** ds2.0r26/lib/lib/include/exits.h Wed Sep 28 19:34:11 2005 --- ds2.0r29/lib/lib/include/exits.h Wed Jul 5 00:01:05 2006 *************** *** 9,15 **** mixed eventFly(object who, string dir); mixed eventGo(object who, string str); ! string GetDoor(string dir); string array GetDoors(); string SetDoor(string dir, string file); string GetDirection(string dest); --- 9,15 ---- mixed eventFly(object who, string dir); mixed eventGo(object who, string str); ! mixed GetDoor(string dir); string array GetDoors(); string SetDoor(string dir, string file); string GetDirection(string dest); diff -c -r --new-file ds2.0r26/lib/lib/interactive.c ds2.0r29/lib/lib/interactive.c *** ds2.0r26/lib/lib/interactive.c Sun Jun 18 16:20:57 2006 --- ds2.0r29/lib/lib/interactive.c Sat Jul 8 23:30:58 2006 *************** *** 31,36 **** --- 31,37 ---- private int Age, WhereBlock, Brief, LoginTime, BirthTime, RescueBit; private string Password, Email, RealName, Rank, LoginSite, HostSite, WebPage; + private string globaltmp; private mapping News; private class marriage *Marriages; private static int LastAge, Setup; *************** *** 263,269 **** lying[s]++; } } - //tc(identify(shorts)); for(i=0, desc = 0, maxi = sizeof(shorts = keys(lying)); i 1 || val >1 ) desc += " are here.%^RESET%^\n"; *************** *** 299,304 **** --- 301,307 ---- i = GetEffectiveVision(); if( i == VISION_CLEAR || i == VISION_LIGHT || i == VISION_DIM ) { mapping lying = ([]), sitting = ([]), standing = ([]), flying = ([]); + mapping furniture = ([]); object *obs; string key; int val; *************** *** 313,320 **** foreach(object liv in obs) { string s = (string)liv->GetHealthShort(); int pos = (int)liv->GetPosition(); - if( !s ) continue; if( pos == POSITION_STANDING) standing[s]++; else if( pos == POSITION_LYING || (int)liv->isFreshCorpse() ) lying[s]++; --- 316,330 ---- foreach(object liv in obs) { string s = (string)liv->GetHealthShort(); int pos = (int)liv->GetPosition(); if( !s ) continue; + if(liv->GetProperty("furniture")) { + s += "BEGIN"+random(999999)+"END"; + } + if(liv->GetProperty("furniture")){ + furniture[s] = liv->GetProperty("furniture"); + } + else if(!furniture[s]) furniture[s] = 0; + if( pos == POSITION_STANDING) standing[s]++; else if( pos == POSITION_LYING || (int)liv->isFreshCorpse() ) lying[s]++; *************** *** 330,348 **** } desc = ""; foreach(key, val in lying) { ! if( val<2 ) desc += capitalize(key) + "%^RESET%^ is lying down."; ! else desc += capitalize(consolidate(val, key)) + "%^RESET%^ are lying down."; desc += "\n"; } foreach(key, val in sitting) { ! if( val<2 ) ! desc += capitalize(key) + "%^RESET%^ is sitting down."; ! else desc += capitalize(consolidate(val, key)) + "%^RESET%^ are sitting down."; desc += "\n"; } foreach(key, val in standing) { if( val<2 ) desc += capitalize(key) + "%^RESET%^ is standing here."; else desc += capitalize(consolidate(val, key)) + --- 340,407 ---- } desc = ""; foreach(key, val in lying) { ! globaltmp = key; ! if(grepp(key,"BEGIN")) { ! sscanf(key,"%sBEGIN%*s",key); ! } ! ! if(lying[globaltmp]>1 && !furniture[globaltmp]){ ! desc += capitalize(consolidate(val, globaltmp)) + "%^RESET%^ are lying down."; + } + else if(lying[globaltmp]<2 && !furniture[globaltmp]){ + desc += capitalize(key) + "%^RESET%^ is lying down."; + } + else if(furniture[globaltmp]) { + desc += capitalize(key) + "%^RESET%^ is lying down"+ + ((furniture[globaltmp]) ? furniture[globaltmp] : "") +"."; + } + else if(furniture[key]) { + desc += capitalize(key) + "%^RESET%^ is lying down"+ + ((furniture[key]) ? furniture[key] : "") +"."; + } + + + else { + desc += "wtf. i am "+key+", furniture["+globaltmp+"] is: "+furniture[globaltmp]+"\n"+ + " furniture["+key+"] is: "+furniture[key]+", and val is: "+val; + } + desc += "\n"; } foreach(key, val in sitting) { ! globaltmp = key; ! if(grepp(key,"BEGIN")) { ! sscanf(key,"%sBEGIN%*s",key); ! } ! ! if(sitting[globaltmp]>1 && !furniture[globaltmp]){ ! desc += capitalize(consolidate(val, globaltmp)) + "%^RESET%^ are sitting down."; + } + else if(sitting[globaltmp]<2 && !furniture[globaltmp]){ + desc += capitalize(key) + "%^RESET%^ is sitting down."; + } + else if(furniture[globaltmp]) { + desc += capitalize(key) + "%^RESET%^ is sitting down"+ + ((furniture[globaltmp]) ? furniture[globaltmp] : "") +"."; + } + else if(furniture[key]) { + desc += capitalize(key) + "%^RESET%^ is sitting down"+ + ((furniture[key]) ? furniture[key] : "") +"."; + } + + + else { + desc += "wtf. i am "+key+", furniture["+globaltmp+"] is: "+furniture[globaltmp]+"\n"+ + " furniture["+key+"] is: "+furniture[key]+", and val is: "+val; + } desc += "\n"; } foreach(key, val in standing) { + if(grepp(key,"BEGIN")) { + sscanf(key,"%sBEGIN%*s",key); + } if( val<2 ) desc += capitalize(key) + "%^RESET%^ is standing here."; else desc += capitalize(consolidate(val, key)) + diff -c -r --new-file ds2.0r26/lib/lib/language.c ds2.0r29/lib/lib/language.c *** ds2.0r26/lib/lib/language.c Wed Apr 5 19:33:18 2006 --- ds2.0r29/lib/lib/language.c Wed Jul 5 00:00:58 2006 *************** *** 6,11 **** --- 6,13 ---- #include + int Polyglot = 0; + class comprehension { function check; int time; *************** *** 123,128 **** --- 125,140 ---- if( val["native"] ) return Languages[lang]["name"]; } + int SetPolyglot(int i){ + if(!i) Polyglot = 0; + else Polyglot = 1; + return Polyglot; + } + + int GetPolyglot(){ + return Polyglot; + } + static void heart_beat() { if( Comprehension ) { Comprehension->time -= GetHeartRate(); diff -c -r --new-file ds2.0r26/lib/lib/living.c ds2.0r29/lib/lib/living.c *** ds2.0r26/lib/lib/living.c Thu Jun 1 23:22:24 2006 --- ds2.0r29/lib/lib/living.c Sat Jul 8 23:30:58 2006 *************** *** 31,36 **** --- 31,40 ---- isPK = 0; } + int SetDead(int i){ + return combat::SetDead(i); + } + int is_living() { return 1; } int inventory_accessible() { return 1; } *************** *** 609,614 **** --- 613,622 ---- return (carry::GetCarriedMass()); } + varargs int GetMaxHealthPoints(string limb){ + return combat::GetMaxHealthPoints(limb); + } + int GetMaxCarry() { return combat::GetMaxCarry(); } int SetPK(int x) { return (isPK = x); } diff -c -r --new-file ds2.0r26/lib/lib/meal.c ds2.0r29/lib/lib/meal.c *** ds2.0r26/lib/lib/meal.c Mon Nov 7 13:29:00 2005 --- ds2.0r29/lib/lib/meal.c Sun Jul 9 19:04:29 2006 *************** *** 60,65 **** --- 60,66 ---- mixed eventDrink(object who) { mixed tmp; int x; + object ob; if( (tmp = (mixed)who->eventDrink(this_object())) != 1 ) return tmp; if( (x = functionp(MyMessage)) && !(x & FP_OWNER_DESTED) ) { *************** *** 75,100 **** who->eventPrint( capitalize(mymsg) ); environment(who)->eventPrint( capitalize(othermsg), who ); } - if( GetEmptyItem() ) { - object ob; ! ob = new(GetEmptyItem() || LIB_ITEM); ! if( base_name(ob) == LIB_ITEM ) { ! ob->SetKeyName(GetEmptyName()); ! ob->SetId( ({ GetEmptyName(), "container", "empty container" }) ); ! ob->SetShort(GetEmptyShort()); ! ob->SetLong(GetEmptyLong()); ! ob->SetValue(10); ! ob->SetMass(100); ! ob->SetDestroyOnSell(); ! } ! if( !((int)ob->eventMove(who)) ) { ! who->eventPrint("You drop " + (string)ob->GetShort() + "."); ! environment(who)->eventPrint((string)who->GetName() + ! " drops " + (string)ob->GetShort() + ".", who); ! ob->eventMove(environment(who)); ! } } if( x = GetPoison() ) { if( random((int)who->GetStatLevel("luck")) > 35 ) who->eventPrint("That didn't seem to taste quite right."); --- 76,99 ---- who->eventPrint( capitalize(mymsg) ); environment(who)->eventPrint( capitalize(othermsg), who ); } ! ob = new(GetEmptyItem() || LIB_ITEM); ! if( base_name(ob) == LIB_ITEM ) { ! ob->SetKeyName(GetEmptyName()); ! ob->SetId( ({ GetEmptyName(), "container", "empty container" }) ); ! ob->SetShort(GetEmptyShort()); ! ob->SetLong(GetEmptyLong()); ! ob->SetBaseCost(1); ! ob->SetMass(10); ! ob->SetDestroyOnSell(); ! } ! if( !((int)ob->eventMove(who)) ) { ! who->eventPrint("You drop " + (string)ob->GetShort() + "."); ! environment(who)->eventPrint((string)who->GetName() + ! " drops " + (string)ob->GetShort() + ".", who); ! ob->eventMove(environment(who)); } + if( x = GetPoison() ) { if( random((int)who->GetStatLevel("luck")) > 35 ) who->eventPrint("That didn't seem to taste quite right."); diff -c -r --new-file ds2.0r26/lib/lib/npc.c ds2.0r29/lib/lib/npc.c *** ds2.0r26/lib/lib/npc.c Sun Jun 18 16:20:57 2006 --- ds2.0r29/lib/lib/npc.c Sat Jul 8 23:30:58 2006 *************** *** 25,30 **** --- 25,31 ---- inherit LIB_SAVE; private int CustomXP, ActionChance, CombatActionChance, AutoStand, Mount; + private int MaximumHealth = 0; private mixed Encounter; private string *EnemyNames; private static int Level, Unique; *************** *** 392,397 **** --- 393,400 ---- varargs int eventDie(mixed agent) { int x; + if(this_object()->GetDead() || this_object()->GetDeathEvents()) return 0; + if( (x = living::eventDie(agent)) != 1 ) return x; if( stringp(Die) ) { message("other_action", Die, environment(), ({ this_object() })); *************** *** 406,411 **** --- 409,415 ---- } set_heart_beat(0); call_out( (: Destruct :), 0); + flush_messages(); return 1; } *************** *** 603,610 **** return GetHealthPoints(); } int SetMaxHealthPoints(int x) { ! SetStat("durability", to_int((x-50)/10), GetStatClass("durability")); return GetMaxHealthPoints(); } --- 607,620 ---- return GetHealthPoints(); } + varargs int GetMaxHealthPoints(string limb){ + if(MaximumHealth) return MaximumHealth; + else return living::GetMaxHealthPoints(limb); + } + int SetMaxHealthPoints(int x) { ! if(x) MaximumHealth = x; ! else SetStat("durability", to_int((x-50)/10), GetStatClass("durability")); return GetMaxHealthPoints(); } *************** *** 633,645 **** } varargs void SetCurrency(mixed val, int amount) { ! if( stringp(val) ) AddCurrency(val, amount - GetCurrency(val)); else if( mapp(val) ) { string *currs; int i; i = sizeof(currs = keys(val)); ! while(i--) AddCurrency(currs[i], val[currs[i]]-GetCurrency(currs[i])); } else error("Bad argument 1 to SetCurrency()."); } --- 643,657 ---- } varargs void SetCurrency(mixed val, int amount) { ! //tc("val: "+identify(val),"red"); ! //if(amount) tc("amount: "+identify(amount),"red"); ! if( stringp(val) ) AddCurrency(val, amount); else if( mapp(val) ) { string *currs; int i; i = sizeof(currs = keys(val)); ! while(i--) AddCurrency(currs[i], val[currs[i]]); } else error("Bad argument 1 to SetCurrency()."); } diff -c -r --new-file ds2.0r26/lib/lib/pile.c ds2.0r29/lib/lib/pile.c *** ds2.0r26/lib/lib/pile.c Sat Apr 22 15:15:26 2006 --- ds2.0r29/lib/lib/pile.c Sat Jul 8 23:30:58 2006 *************** *** 10,21 **** inherit LIB_ITEM; ! private string PileType = 0; ! private int PileAmount = 0; static void create() { string *saveds; item::create(); saveds = item::GetSave(); saveds += ({ "PileType", "PileAmount" }); AddSave( saveds ); --- 10,22 ---- inherit LIB_ITEM; ! string PileType = 0; ! int PileAmount = 0; static void create() { string *saveds; item::create(); + SetNoCondition(1); saveds = item::GetSave(); saveds += ({ "PileType", "PileAmount" }); AddSave( saveds ); *************** *** 27,42 **** id = item::GetId(); if( PileType ) { ! id += ({ PileType, PileAmount + " " + PileType }); } ! return ({ id..., "money", "pile" }); ! } ! ! varargs string GetLong(string str) { ! if( !PileAmount ) { ! return 0; ! } ! return "It is a pile of " + PileAmount + " " + PileType + "."; } int GetMass() { --- 28,36 ---- id = item::GetId(); if( PileType ) { ! id += ({ PileType, PileAmount + " " + PileType, "pile of "+PileType }); } ! return ({ id..., "money", "pile", "pile of "+ PileAmount + " " + PileType }); } int GetMass() { *************** *** 46,51 **** --- 40,50 ---- void SetPile(string str, int amt) { PileType = str; PileAmount = amt; + if(!PileAmount || PileAmount < 1 ){ + SetLong("a pile of money"); + call_out( (: eventDestruct :), 1); + } + else SetLong("It is a pile of " + PileAmount + " " + PileType + "."); parse_refresh(); } *************** *** 56,61 **** --- 55,64 ---- string GetShort() { string str = item::GetShort(); + if(!PileAmount || PileAmount < 1 ){ + call_out( (: eventDestruct :), 1); + return "a pile of money"; + } if( str ) { return str; } *************** *** 84,98 **** int x; x = item::eventMove(dest); ! if( !living(environment()) ) { return x; } - environment()->AddCurrency(PileType, PileAmount); - environment()->AddCarriedMass(-this_object()->GetMass()); - SetShort("a pile of " + PileAmount + " " + PileType); - PileAmount = 0; - call_out((: Destruct :), 0); - return x; } mixed direct_get_wrd_wrd_out_of_obj(string num, string curr) { --- 87,104 ---- int x; x = item::eventMove(dest); ! if( environment() && !living(environment()) ) { ! return x; ! } ! ! if(environment() && living(environment())){ ! environment()->AddCurrency(PileType, PileAmount); ! environment()->AddCarriedMass(-this_object()->GetMass()); ! SetShort("a pile of " + PileAmount + " " + PileType); ! PileAmount = 0; ! call_out((: Destruct :), 0); return x; } } mixed direct_get_wrd_wrd_out_of_obj(string num, string curr) { *************** *** 122,124 **** --- 128,138 ---- mixed direct_get_wrd_wrd_from_obj(string amt, string curr) { return direct_get_wrd_wrd_out_of_obj(amt, curr); } + + void init(){ + ::init(); + if(!PileAmount || PileAmount < 1 ){ + SetLong("some money"); + call_out( (: eventDestruct :), 1); + } + } diff -c -r --new-file ds2.0r26/lib/lib/player.c ds2.0r29/lib/lib/player.c *** ds2.0r26/lib/lib/player.c Sun Jun 18 16:20:58 2006 --- ds2.0r29/lib/lib/player.c Wed Jul 5 19:58:20 2006 *************** *** 22,28 **** private string *Titles; string *Muffed = ({}); private class quest *Quests; ! private class death *Deaths; private int TrainingPoints, TitleLength; /* ***************** /lib/player.c driver applies ***************** */ --- 22,28 ---- private string *Titles; string *Muffed = ({}); private class quest *Quests; ! private mapping *Deaths; private int TrainingPoints, TitleLength; /* ***************** /lib/player.c driver applies ***************** */ *************** *** 125,162 **** int x, expee, subexpee; if( (x = living::eventDie(agent)) != 1 ) return x; ! if( !GetUndead() ) { ! eventDestroyUndead(agent); ! } ! else { ! message("my_action", "Consciousness passes from you after one last " ! "gasp for air.", this_object()); ! message("my_action", "You awake, but you find your body feels " ! "different, and the world about you is unfamiliar.", ! this_object()); ! if( agent ) { ! message("other_action", GetName() + " drops dead by the hand " ! "of " + (string)agent->GetName() + ".", ! environment(this_object()), ({ agent, this_object() })); ! message("other_action", "You send " + GetName() + " into the " ! "Underworld.", agent); ! } ! else message("other_action", GetName() + " drops dead.", ! environment(), ({ this_object() }) ); ! ! NewBody(GetRace()); ! ! expee = this_object()->GetExperiencePoints(); ! subexpee = to_int(expee * 0.25); ! ! eventCompleteHeal(GetMaxHealthPoints()/2); ! AddMagicPoints(-(random(GetMagicPoints()))); ! interactive::eventMove(ROOM_DEATH); ! this_object()->AddExperiencePoints(-subexpee); ! this_object()->save_player((string)this_object()->GetKeyName()); ! this_object()->eventForce("look"); } ! return 1; } mixed eventTurn(object who) { --- 125,168 ---- int x, expee, subexpee; if( (x = living::eventDie(agent)) != 1 ) return x; ! ! if(!Deaths || !sizeof(Deaths)) ! Deaths = ({([ "date" : ctime(time()), "enemy" : ((agent->GetName()) ? agent->GetName() : agent) ])}); ! else Deaths += ({ ([ "date" : ctime(time()), "enemy" : agent->GetName() ]) }); ! ! if( !GetUndead() ) { ! eventDestroyUndead(agent); ! } ! else { ! message("my_action", "Consciousness passes from you after one last " ! "gasp for air.", this_object()); ! message("my_action", "You awake, but you find your body feels " ! "different, and the world about you is unfamiliar.", ! this_object()); ! if( agent ) { ! message("other_action", GetName() + " drops dead by the hand " ! "of " + (string)agent->GetName() + ".", ! environment(this_object()), ({ agent, this_object() })); ! message("other_action", "You send " + GetName() + " into the " ! "Underworld.", agent); } ! else message("other_action", GetName() + " drops dead.", ! environment(), ({ this_object() }) ); ! ! NewBody(GetRace()); ! ! expee = this_object()->GetExperiencePoints(); ! subexpee = to_int(expee * 0.25); ! ! eventCompleteHeal(GetMaxHealthPoints()/2); ! AddMagicPoints(-(random(GetMagicPoints()))); ! interactive::eventMove(ROOM_DEATH); ! this_object()->AddExperiencePoints(-subexpee); ! this_object()->save_player((string)this_object()->GetKeyName()); ! this_object()->eventForce("look"); ! } ! flush_messages(); ! return 1; } mixed eventTurn(object who) { *************** *** 170,175 **** --- 176,184 ---- void eventRevive() { string skill; + this_object()->SetDead(0); + this_object()->SetDeathEvents(0); + if( !GetUndead() ) return; SetUndead(0); if(this_player()->GetPoison() > 0){ *************** *** 527,533 **** return Muffed; } - string *SetTitles(string *titles) { if( sizeof(distinct_array(titles)) != sizeof(titles) ) return Titles; Titles = titles; --- 536,541 ---- *************** *** 782,829 **** mapping *GetDeaths() { if( !Deaths ) return ({}); ! return map(Deaths, function(class death morte) { ! return ([ "date" : morte->Date, ! "enemy" : morte->Enemy ]); ! }); ! } ! ! int AddTrainingPoints(int x) { ! log_file("TrainingPoints", GetName() + " received " + x + " training " ! "points at " + ctime(time()) + "\ncall chain: " + ! sprintf("%O\n", previous_object(-1)) ); ! return (TrainingPoints += x); ! } ! ! int RemoveTrainingPoints(int x) { ! return (TrainingPoints -= x); ! } ! ! int GetTrainingPoints() { return TrainingPoints; } ! ! varargs int eventTrain(string skill, int points) { ! float x = 0; ! mapping mp; ! ! if( points < 1 ) points = 1; ! if( !(mp = GetSkill(skill)) ) return 0; ! if( TrainingPoints < points ) return 0; ! while( points-- ) { ! int max = GetMaxSkillPoints(skill, mp["level"]); ! switch( mp["class"] ) { ! case 1: x = 50.0; break; ! case 2: x = 40.0; break; ! case 3: x = 30.0; break; ! case 4: x = 20.0; break; ! default: return 0; ! } ! TrainingPoints--; ! AddSkillPoints(skill, to_int( (max * x) / 100 )); } ! return 1; } ! //string ChangeClass(string cl) { ! // error("Players cannot change class.\n"); ! // return GetClass(); ! // } --- 790,834 ---- mapping *GetDeaths() { if( !Deaths ) return ({}); ! return copy(Deaths); ! } ! ! int AddTrainingPoints(int x) { ! log_file("TrainingPoints", GetName() + " received " + x + " training " ! "points at " + ctime(time()) + "\ncall chain: " + ! sprintf("%O\n", previous_object(-1)) ); ! return (TrainingPoints += x); ! } ! ! int RemoveTrainingPoints(int x) { ! return (TrainingPoints -= x); ! } ! ! int GetTrainingPoints() { return TrainingPoints; } ! ! varargs int eventTrain(string skill, int points) { ! float x = 0; ! mapping mp; ! ! if( points < 1 ) points = 1; ! if( !(mp = GetSkill(skill)) ) return 0; ! if( TrainingPoints < points ) return 0; ! while( points-- ) { ! int max = GetMaxSkillPoints(skill, mp["level"]); ! switch( mp["class"] ) { ! case 1: x = 50.0; break; ! case 2: x = 40.0; break; ! case 3: x = 30.0; break; ! case 4: x = 20.0; break; ! default: return 0; } ! TrainingPoints--; ! AddSkillPoints(skill, to_int( (max * x) / 100 )); } + return 1; + } ! //string ChangeClass(string cl) { ! // error("Players cannot change class.\n"); ! // return GetClass(); ! // } diff -c -r --new-file ds2.0r26/lib/lib/props/clean.c ds2.0r29/lib/lib/props/clean.c *** ds2.0r26/lib/lib/props/clean.c Mon Jan 16 23:03:15 2006 --- ds2.0r29/lib/lib/props/clean.c Sat Jul 8 23:30:59 2006 *************** *** 29,35 **** * another object, call ob->eventDestruct(). */ static int Destruct() { ! object env; if( !this_object() ) { return 1; --- 29,35 ---- * another object, call ob->eventDestruct(). */ static int Destruct() { ! object env, furn; if( !this_object() ) { return 1; *************** *** 42,47 **** --- 42,51 ---- } } } + + if(living(this_object()) && furn = this_object()->GetProperty("furniture_object")) + if(objectp(furn)) furn->eventReleaseStand(this_object()); + remove_call_out(); destruct(this_object()); return !(this_object()); diff -c -r --new-file ds2.0r26/lib/lib/props/move.c ds2.0r29/lib/lib/props/move.c *** ds2.0r26/lib/lib/props/move.c Mon Jan 23 15:46:02 2006 --- ds2.0r29/lib/lib/props/move.c Sat Jul 8 23:30:59 2006 *************** *** 9,15 **** } int eventMove(mixed dest) { ! object ob,to; int depth; to=this_object(); --- 9,15 ---- } int eventMove(mixed dest) { ! object ob,to,furn; int depth; to=this_object(); *************** *** 77,81 **** --- 77,85 ---- } } } + + if(living(this_object()) && furn = this_object()->GetProperty("furniture_object")) + if(objectp(furn)) furn->eventReleaseStand(this_object()); + return (LastEnvironment != environment()); } diff -c -r --new-file ds2.0r26/lib/lib/sentient.c ds2.0r29/lib/lib/sentient.c *** ds2.0r26/lib/lib/sentient.c Wed Apr 5 19:33:18 2006 --- ds2.0r29/lib/lib/sentient.c Wed Jul 5 00:00:58 2006 *************** *** 265,281 **** mixed eventWander() { int fp; if( !sizeof(WanderPath) ) { string *sorties; string tmp; sorties = ({}); foreach(tmp in (string *)environment()->GetExits()) { string dest, door; if( !permit_load && !find_object(dest = (string)environment()->GetExit(tmp)) ) continue; ! if( (door = (string)environment()->GetDoor(tmp)) && (int)door->GetClosed() ) continue; sorties += ({ "go " + tmp }); } --- 265,285 ---- mixed eventWander() { int fp; + //tc("1","red"); + if( !sizeof(WanderPath) ) { string *sorties; string tmp; + //tc("2","green"); sorties = ({}); foreach(tmp in (string *)environment()->GetExits()) { string dest, door; if( !permit_load && !find_object(dest = (string)environment()->GetExit(tmp)) ) continue; ! door = (string)environment()->GetDoor(tmp); ! if( door && (int)door->GetClosed() ) continue; sorties += ({ "go " + tmp }); } *************** *** 284,290 **** if( !find_object(dest = (string)environment()->GetEnter(tmp)) ) continue; ! if( (door = (string)environment()->GetDoor(tmp)) && (int)door->GetClosed() ) continue; sorties += ({ "enter " + tmp }); } --- 288,295 ---- if( !find_object(dest = (string)environment()->GetEnter(tmp)) ) continue; ! door = (string)environment()->GetDoor(tmp); ! if( door && (int)door->GetClosed() ) continue; sorties += ({ "enter " + tmp }); } *************** *** 327,338 **** --- 332,347 ---- return; } if( !GetInCombat() ) { // Things to do when not in combat + //tc("not in combat"); if( WanderSpeed ) { // Check if wandering + //tc("wandering"); if( WanderCount >= WanderSpeed ) { // Time to wander + //tc("time to wander"); WanderCount = 0; eventWander(); } else { + //tc("not time to wander yet"); WanderCount++; } } diff -c -r --new-file ds2.0r26/lib/lib/std/bed.c ds2.0r29/lib/lib/std/bed.c *** ds2.0r26/lib/lib/std/bed.c Sun Dec 11 21:15:29 2005 --- ds2.0r29/lib/lib/std/bed.c Sun Jul 9 22:06:37 2006 *************** *** 1,17 **** #include inherit LIB_ITEM; - inherit LIB_SIT; inherit LIB_LIE; inherit LIB_SURFACE; void create(){ ! ::create(); ! SetMaxSitters(4); SetMaxLiers(2); SetMaxCarry(300); SetMass(1700); } --- 1,23 ---- #include inherit LIB_ITEM; inherit LIB_LIE; inherit LIB_SURFACE; void create(){ ! item::create(); ! surface::create(); ! ! SetMaxLiers(4); SetMaxLiers(2); SetMaxCarry(300); SetMass(1700); } + int CanGet(object who){ + if(lie::CanGet(who)) + return item::CanGet(who); + else return 0; + } diff -c -r --new-file ds2.0r26/lib/lib/std/chair.c ds2.0r29/lib/lib/std/chair.c *** ds2.0r26/lib/lib/std/chair.c Sun Dec 11 21:15:30 2005 --- ds2.0r29/lib/lib/std/chair.c Sun Jul 9 22:06:37 2006 *************** *** 19,22 **** --- 19,28 ---- SetMass(500); } + int CanGet(object who){ + if(sit::CanGet(who)) + return item::CanGet(who); + else return 0; + } + /* Nothing else needs to happen here */ diff -c -r --new-file ds2.0r26/lib/lib/std/corpse.c ds2.0r29/lib/lib/std/corpse.c *** ds2.0r26/lib/lib/std/corpse.c Sat Mar 11 11:16:12 2006 --- ds2.0r29/lib/lib/std/corpse.c Fri Jul 7 19:41:43 2006 *************** *** 74,80 **** Race = who->GetRace(); Count = 1; Fresh = 1; ! SetShort((string)who->GetShort()); SetLong("As you look closely at " + who->GetCapName() + ", you notice that " + nominative(who) + " does not appear to be moving."); --- 74,80 ---- Race = who->GetRace(); Count = 1; Fresh = 1; ! SetShort("the corpse of "+(string)who->GetShort()); SetLong("As you look closely at " + who->GetCapName() + ", you notice that " + nominative(who) + " does not appear to be moving."); diff -c -r --new-file ds2.0r26/lib/lib/std/room.c ds2.0r29/lib/lib/std/room.c *** ds2.0r26/lib/lib/std/room.c Sun Jun 18 16:20:59 2006 --- ds2.0r29/lib/lib/std/room.c Wed Jul 5 00:01:05 2006 *************** *** 945,951 **** if(member_array("down",exits) != -1) dir_string += "d, "; if(member_array("out",exits) != -1) dir_string += "out, "; if(sizeof(this_object()->GetEnters(1) - ({0}) )) { ! dir_string += ", "; dir_string += enters; } if(last(dir_string,2) == ", ") dir_string = truncate(dir_string,2); --- 945,951 ---- if(member_array("down",exits) != -1) dir_string += "d, "; if(member_array("out",exits) != -1) dir_string += "out, "; if(sizeof(this_object()->GetEnters(1) - ({0}) )) { ! if(sizeof(this_object()->GetExits())) dir_string += ", "; dir_string += enters; } if(last(dir_string,2) == ", ") dir_string = truncate(dir_string,2); diff -c -r --new-file ds2.0r26/lib/lib/std/table.c ds2.0r29/lib/lib/std/table.c *** ds2.0r26/lib/lib/std/table.c Sun Dec 11 21:20:49 2005 --- ds2.0r29/lib/lib/std/table.c Sun Jul 9 22:06:38 2006 *************** *** 1,14 **** #include ! inherit LIB_ITEM; ! inherit LIB_SIT; ! inherit LIB_LIE; ! ! inherit LIB_STORAGE; ! inherit LIB_SURFACE; void create(){ ! storage::create(); SetMaxSitters(2); SetMaxLiers(1); SetMaxCarry(500); --- 1,11 ---- #include ! inherit LIB_BED; void create(){ ! bed::create(); ! SetShort("A table"); ! SetLong("A table"); SetMaxSitters(2); SetMaxLiers(1); SetMaxCarry(500); *************** *** 17,20 **** --- 14,24 ---- inventory_accessible(); } + void init(){ + ::init(); + } + + int CanGet(object who){ + return bed::CanGet(who); + } diff -c -r --new-file ds2.0r26/lib/lib/std/vendor.c ds2.0r29/lib/lib/std/vendor.c *** ds2.0r26/lib/lib/std/vendor.c Sat Apr 22 15:15:31 2006 --- ds2.0r29/lib/lib/std/vendor.c Sun Jul 9 19:04:29 2006 *************** *** 94,100 **** eventForce("say " + (string)ob->GetShort() + "! Excellent!"); if(bargain) who->AddSkillPoints("bargaining", value*5); message("my_action", "You sell " + (string)ob->GetShort() + ".", who); ! message("other_action", (string)who->GetKeyName() + " sells " + (string)ob->GetShort() + ".", environment(), ({ who, this_object() })); ob->eventDestruct(); --- 94,100 ---- eventForce("say " + (string)ob->GetShort() + "! Excellent!"); if(bargain) who->AddSkillPoints("bargaining", value*5); message("my_action", "You sell " + (string)ob->GetShort() + ".", who); ! message("other_action", capitalize((string)who->GetKeyName()) + " sells " + (string)ob->GetShort() + ".", environment(), ({ who, this_object() })); ob->eventDestruct(); *************** *** 115,126 **** if(bargain) who->AddSkillPoints("bargaining", value*5); tmp += ({ ob }); message("my_action", "You sell " + (string)ob->GetShort() + ".", who); ! message("other_action", (string)who->GetKeyName() + " sells " + (string)ob->GetShort() + ".", environment(), ({ who, this_object() })); } if( !sizeof(tmp) ) ! eventForce("say I am sorry, " + (string)who->GetKeyName() + ", " "that we could not come to a better agreement."); else map(tmp, function(object ob) { if( (int)ob->GetDestroyOnSell() ) --- 115,126 ---- if(bargain) who->AddSkillPoints("bargaining", value*5); tmp += ({ ob }); message("my_action", "You sell " + (string)ob->GetShort() + ".", who); ! message("other_action", capitalize((string)who->GetKeyName()) + " sells " + (string)ob->GetShort() + ".", environment(), ({ who, this_object() })); } if( !sizeof(tmp) ) ! eventForce("say I am sorry, " + capitalize((string)who->GetKeyName()) + ", " "that we could not come to a better agreement."); else map(tmp, function(object ob) { if( (int)ob->GetDestroyOnSell() ) *************** *** 170,176 **** eventForce("say I have no such thing to show you"); return 1; } ! message("other_action", GetKeyName()+" shows you "+ (string)ob->GetShort()+".", who); message("system", (string)ob->GetLong(), who); return 1; --- 170,176 ---- eventForce("say I have no such thing to show you"); return 1; } ! message("other_action", capitalize(GetKeyName())+" shows you "+ (string)ob->GetShort()+".", who); message("system", (string)ob->GetLong(), who); return 1; *************** *** 200,209 **** list2 += ({ ( obs[counter]->GetKeyName()) }); } } ! obs2 = ({ present(list2[0],sroom) }); ! maxi = sizeof(list2); ! for(int counter = 1;counter < maxi;++counter) { ! obs2 += ({ present(list2[counter],sroom) }); } maxi = sizeof(obs2); i = (int)this_player()->GetScreen()[0]; --- 200,218 ---- list2 += ({ ( obs[counter]->GetKeyName()) }); } } ! //obs2 = ({ present(list2[0],sroom) }); ! //maxi = sizeof(list2); ! //for(int counter = 1;counter < maxi;++counter) { ! // obs2 += ({ present(list2[counter],sroom) }); ! // } ! obs2 = ({}); ! foreach(object tempob in obs){ ! string *base_names = ({}); ! foreach( object tempob2 in obs2 ) base_names += ({ base_name(tempob2) }); ! if(!sizeof(obs2)) { ! obs2 = ({tempob}); ! } ! else if(member_array(base_name(tempob), base_names) == -1) obs2 += ({ tempob }); } maxi = sizeof(obs2); i = (int)this_player()->GetScreen()[0]; *************** *** 318,326 **** cost=to_int(ob->GetBaseCost() / ECONOMY_D->__Query(LocalCurrency,"rate")); } else cost=to_int(floor(ob->GetBaseCost())); ! if(cost && cost > 0) x=cost; ! if(!cost || cost < 0) x = to_int(floor(GetValue(ob, this_player()))); ! eventForce("say " + (string)who->GetKeyName() + ", I will offer " "you " + x + " " + GetLocalCurrency() + " for " + (string)ob->GetShort()); return 1; --- 327,339 ---- cost=to_int(ob->GetBaseCost() / ECONOMY_D->__Query(LocalCurrency,"rate")); } else cost=to_int(floor(ob->GetBaseCost())); ! if(!cost || cost < 1){ ! eventForce("say " + capitalize((string)who->GetKeyName()) + ", I will not buy " ! "that worthless thing from you."); ! return 1; ! } ! else x=cost; ! eventForce("say " + capitalize((string)who->GetKeyName()) + ", I will offer " "you " + x + " " + GetLocalCurrency() + " for " + (string)ob->GetShort()); return 1; *************** *** 343,367 **** return 0; } obs = all_inventory(sroom); ! maxi = sizeof(obs); if( x = to_int(args) ) { ! list2 = ({(obs[0]->GetKeyName())}); for(int counter = 1;counter < maxi;++counter) { ! if(member_array((obs[counter]->GetKeyName()),list2) < 0) { ! list2 += ({ ( obs[counter]->GetKeyName()) }); } } - obs2 = ({ present(list2[0],sroom) }); maxi = sizeof(list2); ! for(int counter = 1;counter < maxi;++counter) { ! obs2 += ({ present(list2[counter],sroom) }); ! } ! if((x <= 0) || (x > sizeof(obs2))) ob = 0; ! else ! ob = obs2[x-1]; ! } else ob = present(args = lower_case(args), sroom); if( !ob ) { eventForce("say I have no such thing!"); return 1; --- 356,384 ---- return 0; } obs = all_inventory(sroom); ! obs2 = ({}); ! foreach(object tempob in obs){ ! string *base_names = ({}); ! foreach( object tempob2 in obs2 ) base_names += ({ base_name(tempob2) }); ! if(!sizeof(obs2)) { ! obs2 = ({tempob}); ! } ! else if(member_array(base_name(tempob), base_names) == -1) obs2 += ({ tempob }); ! } ! maxi = sizeof(obs2); if( x = to_int(args) ) { ! list2 = ({(obs2[0]->GetKeyName())}); for(int counter = 1;counter < maxi;++counter) { ! if(member_array((obs2[counter]->GetKeyName()),list2) < 0) { ! list2 += ({ ( obs2[counter]->GetKeyName()) }); } } maxi = sizeof(list2); ! ob = obs2[x-1]; } else ob = present(args = lower_case(args), sroom); + if(!ob) foreach(object tempob in obs2) + if(answers_to(args,tempob)) ob = tempob; if( !ob ) { eventForce("say I have no such thing!"); return 1; *************** *** 370,376 **** eventForce("say that thing has no value!"); return 1; } ! eventForce("say " + (string)who->GetKeyName() + ", I will take " + x + " " + GetLocalCurrency() + " for " + (string)ob->GetShort()); return 1; --- 387,393 ---- eventForce("say that thing has no value!"); return 1; } ! eventForce("say " + capitalize((string)who->GetKeyName()) + ", I will take " + x + " " + GetLocalCurrency() + " for " + (string)ob->GetShort()); return 1; *************** *** 436,455 **** sroom = load_object(StorageRoom); obs = all_inventory(sroom); ! maxi = sizeof(obs); if(number = to_int(what)) { number = number - 1; ! list2 = ({(obs[0]->GetKeyName())}); for(int counter = 1;counter < maxi;++counter) { ! if(member_array((obs[counter]->GetKeyName()),list2) < 0) { ! list2 += ({ ( obs[counter]->GetKeyName()) }); } } - obs2 = ({ present(list2[0],sroom) }); maxi = sizeof(list2); - for(int counter = 1;counter < maxi;++counter) { - obs2 += ({ present(list2[counter],sroom) }); - } if((number >= 0) && (number < sizeof(obs2))) { ob = obs2[number]; } else { --- 453,477 ---- sroom = load_object(StorageRoom); obs = all_inventory(sroom); ! obs2 = ({}); ! foreach(object tempob in obs){ ! string *base_names = ({}); ! foreach( object tempob2 in obs2 ) base_names += ({ base_name(tempob2) }); ! if(!sizeof(obs2)) { ! obs2 = ({tempob}); ! } ! else if(member_array(base_name(tempob), base_names) == -1) obs2 += ({ tempob }); ! } ! maxi = sizeof(obs2); if(number = to_int(what)) { number = number - 1; ! list2 = ({(obs2[0]->GetKeyName())}); for(int counter = 1;counter < maxi;++counter) { ! if(member_array((obs2[counter]->GetKeyName()),list2) < 0) { ! list2 += ({ ( obs2[counter]->GetKeyName()) }); } } maxi = sizeof(list2); if((number >= 0) && (number < sizeof(obs2))) { ob = obs2[number]; } else { *************** *** 457,463 **** return 1; } } else { ! if( !(ob = present(what, sroom)) ) { eventForce("say I have nothing like that to sell"); return 1; } --- 479,488 ---- return 1; } } else { ! if( !(ob = present(what, sroom))) ! foreach(object tempob in obs2) ! if(answers_to(what,tempob)) ob = tempob; ! if(!ob){ eventForce("say I have nothing like that to sell"); return 1; } diff -c -r --new-file ds2.0r26/lib/lib/std/worn_storage.c ds2.0r29/lib/lib/std/worn_storage.c *** ds2.0r26/lib/lib/std/worn_storage.c Mon May 15 01:14:02 2006 --- ds2.0r29/lib/lib/std/worn_storage.c Wed Jul 5 00:01:05 2006 *************** *** 456,462 **** object::create(); holder::create(); seal::create(); - PutCheck(); SetVendorType(VT_ARMOR); } --- 456,461 ---- *************** *** 520,529 **** } int GetOpacity() { ! if( GetClosed() ) { ! return holder::GetOpacity(); ! } ! else return 0; } int GetRadiantLight(int ambient) { --- 519,525 ---- } int GetOpacity() { ! return holder::GetOpacity(); } int GetRadiantLight(int ambient) { diff -c -r --new-file ds2.0r26/lib/lib/talk.c ds2.0r29/lib/lib/talk.c *** ds2.0r26/lib/lib/talk.c Wed Apr 5 19:33:18 2006 --- ds2.0r29/lib/lib/talk.c Wed Jul 5 00:00:58 2006 *************** *** 10,15 **** --- 10,17 ---- #include #include "include/talk.h" + int GetPolyglot(); + int direct_ask_liv_str() { return 1; } int direct_ask_liv_to_str() { return 1; } *************** *** 48,54 **** string msg, string lang) { string tmp; ! if( lang && !newbiep() ) msg = translate(msg, GetLanguageLevel(lang)); switch(cls) { case TALK_PRIVATE: if( target != this_object() ) return 0; --- 50,56 ---- string msg, string lang) { string tmp; ! if( lang && !newbiep() && !GetPolyglot() ) msg = translate(msg, GetLanguageLevel(lang)); switch(cls) { case TALK_PRIVATE: if( target != this_object() ) return 0; *************** *** 126,132 **** string verb, tmp; int cols; ! if( lang ) { msg = translate(msg, GetLanguageLevel(lang)); lang = GetLanguageName(lang); } --- 128,134 ---- string verb, tmp; int cols; ! if( lang && !GetPolyglot() ) { msg = translate(msg, GetLanguageLevel(lang)); lang = GetLanguageName(lang); } diff -c -r --new-file ds2.0r26/lib/lib/teacher.c ds2.0r29/lib/lib/teacher.c *** ds2.0r26/lib/lib/teacher.c Fri May 12 21:15:18 2006 --- ds2.0r29/lib/lib/teacher.c Fri Jul 7 19:41:43 2006 *************** *** 13,19 **** --- 13,70 ---- private string array TeachingLanguages; private mapping Students; + private int commercial = 0; + private int AllLangs = 0; + private int teaching_fee = 50; + private string local_currency = "silver"; + int SetAllLanguages(int i){ + if(!i) AllLangs = 0; + else AllLangs = 1; + return AllLangs; + } + + int GetAllLanguages(){ + return AllLangs; + } + + int GetCommercial(){ + return commercial; + } + + int SetCommercial(int i){ + if(i) { + commercial = i; + if(!teaching_fee) teaching_fee = 50; + } + else commercial = 0; + return commercial; + } + + string GetLocalCurrency(){ + return local_currency; + } + + string SetLocalCurrency(string str){ + local_currency = str; + return local_currency; + } + + int GetTeachingFee(){ + return teaching_fee; + } + + int SetTeachingFee(int i){ + if(i) { + teaching_fee = i; + commercial = 1; + } + else { + teaching_fee = 0; + commercial = 0; + } + return teaching_fee; + } /**** driver applies ****/ *************** *** 113,126 **** eventForce("speak I am already teaching you!"); return 0; } ! if( member_array(language, this_object()->GetTeachingLanguages()) == -1 ) { eventForce("speak I know nothing about the " +capitalize(language)+" language."); return 0; } ! if( (int)this_player()->GetTrainingPoints() < 1 ) { eventForce("speak You need more training points."); return 0; } Students[ (string)who->GetKeyName() ] = language; eventStart(who, language); call_out((: ContinueTeaching, who, language, 0 :), TEACHING_WAIT); --- 164,183 ---- eventForce("speak I am already teaching you!"); return 0; } ! if( !GetAllLanguages() && ! member_array(language, this_object()->GetTeachingLanguages()) == -1 ) { eventForce("speak I know nothing about the " +capitalize(language)+" language."); return 0; } ! if( !commercial && (int)this_player()->GetTrainingPoints() < 1 ) { eventForce("speak You need more training points."); return 0; } + if(commercial && this_player()->GetCurrency(GetLocalCurrency()) < teaching_fee){ + eventForce("speak I charge "+teaching_fee+" "+GetLocalCurrency()+" per lesson. "+ + "You don't seem to have the right amount of the right currency."); + return 0; + } Students[ (string)who->GetKeyName() ] = language; eventStart(who, language); call_out((: ContinueTeaching, who, language, 0 :), TEACHING_WAIT); *************** *** 137,143 **** map_delete(Students, (string)who->GetKeyName()); eventComplete(who, language); who->AddLanguagePoints(language,5+((who->GetStatLevel("intelligence")/10)*2)+random(10)); ! who->AddTrainingPoints(-1); return 1; } else { eventContinue(who, language, ++x); --- 194,201 ---- map_delete(Students, (string)who->GetKeyName()); eventComplete(who, language); who->AddLanguagePoints(language,5+((who->GetStatLevel("intelligence")/10)*2)+random(10)); ! if(!commercial) who->AddTrainingPoints(-1); ! else who->AddCurrency(GetLocalCurrency(),-teaching_fee); return 1; } else { eventContinue(who, language, ++x); diff -c -r --new-file ds2.0r26/lib/lib/teller.c ds2.0r29/lib/lib/teller.c *** ds2.0r26/lib/lib/teller.c Wed Dec 7 14:03:46 2005 --- ds2.0r29/lib/lib/teller.c Sat Jul 8 23:30:59 2006 *************** *** 22,27 **** --- 22,29 ---- sentient::create(); BankName = "Town Trust"; LocalCurrency = "silver"; + LocalFee = 1; + NonLocalFee = 5; OpenFee = 5; Currencies = ({ "copper", "silver", "electrum", "gold", "platinum" }); SetCommandResponses( ([ *************** *** 91,102 **** "surcharge of %d %s.", type, charge, currency)); return amount; } ! else if( (amount + charge) <= (int)who->GetCurrency(currency) ) { ! who->eventPrint(sprintf("The bank charges you a %s %d %s " ! "surcharge.", type, charge, currency)); ! who->AddCurrency(currency, -charge); ! return amount; ! } else { who->eventPrint(sprintf("You are unable to afford the " "%s surcharge of %d %s.", type, charge, currency)); return 0; --- 93,105 ---- "surcharge of %d %s.", type, charge, currency)); return amount; } ! //else if( (amount + charge) <= (int)who->GetCurrency(currency) ) { ! // who->eventPrint(sprintf("The bank charges you a %s %d %s " ! // "surcharge.", type, charge, currency)); ! //who->AddCurrency(currency, -charge); ! // return amount; ! // } ! else { who->eventPrint(sprintf("You are unable to afford the " "%s surcharge of %d %s.", type, charge, currency)); return 0; *************** *** 167,173 **** } int eventWithdraw(object who, string currency, int amount) { ! int i, x; x = amount; if( amount < 1 ) { --- 170,176 ---- } int eventWithdraw(object who, string currency, int amount) { ! int i, x, charge; x = amount; if( amount < 1 ) { *************** *** 186,201 **** return 1; } if( !(amount = AddSurcharge(who, currency, amount)) ) return 1; ! if( (int)who->AddCurrency(currency, amount) < 0 ) { eventForce("speak You are unable to carry that " "much "+currency+"!"); ! if( x > amount ) { ! who->eventPrint("The bank returns the fee."); ! who->AddCurrency(currency, (amount - x)); ! } return 1; } ! who->AddBank(GetBankName(), currency, -amount); who->eventPrint(sprintf("You withdraw %d %s from your account.", amount, currency)); environment()->eventPrint(sprintf("%s withdraws some %s.", --- 189,206 ---- return 1; } if( !(amount = AddSurcharge(who, currency, amount)) ) return 1; ! charge = x - amount; ! if( (int)who->AddCurrency(currency, x) < 0 ) { eventForce("speak You are unable to carry that " "much "+currency+"!"); ! //if( x > amount ) { ! who->eventPrint("The bank credits your account with the fee."); ! //who->AddCurrency(currency, (amount - x)); ! //} return 1; } ! who->AddCurrency(currency, -charge); ! who->AddBank(GetBankName(), currency, -x); who->eventPrint(sprintf("You withdraw %d %s from your account.", amount, currency)); environment()->eventPrint(sprintf("%s withdraws some %s.", diff -c -r --new-file ds2.0r26/lib/news/creator ds2.0r29/lib/news/creator *** ds2.0r26/lib/news/creator Mon May 15 11:29:43 2006 --- ds2.0r29/lib/news/creator Wed Jul 5 00:00:58 2006 *************** *** 2,12 **** /news/creator ! Dead Souls Admin FAQ: http://dead-souls.sourceforge.net/ds-admin-faq.html ! Dead Souls Creator FAQ: http://dead-souls.sourceforge.net/ds-creator-faq.html ! Editor tutorial: http://dead-souls.sourceforge.net/editor.html The Creators Manual has been updated and revised! --- 2,12 ---- /news/creator ! Dead Souls Admin FAQ: http://dead-souls.net/ds-admin-faq.html ! Dead Souls Creator FAQ: http://dead-souls.net/ds-creator-faq.html ! Editor tutorial: http://dead-souls.net/editor.html The Creators Manual has been updated and revised! diff -c -r --new-file ds2.0r26/lib/news/deadsouls ds2.0r29/lib/news/deadsouls *** ds2.0r26/lib/news/deadsouls Sun Jun 18 16:20:59 2006 --- ds2.0r29/lib/news/deadsouls Wed Jul 5 00:00:58 2006 *************** *** 11,14 **** *-> This demo MUD grants creator powers to guests. The <-* *-> regular, downloadable version does not do this. <-* ---------------------------------------------------------- ! For more info: http://dead-souls.sourceforge.net/ --- 11,14 ---- *-> This demo MUD grants creator powers to guests. The <-* *-> regular, downloadable version does not do this. <-* ---------------------------------------------------------- ! For more info: http://dead-souls.net/ diff -c -r --new-file ds2.0r26/lib/news/hints.txt ds2.0r29/lib/news/hints.txt *** ds2.0r26/lib/news/hints.txt Sun Dec 18 12:51:00 2005 --- ds2.0r29/lib/news/hints.txt Wed Jul 5 00:00:58 2006 *************** *** 1,7 **** CREATOR TIPS * For details on the Quick Creation System: ! http://dead-souls.sourceforge.net/example.html * Admins: there is a new command: admintool --- 1,13 ---- CREATOR TIPS * For details on the Quick Creation System: ! http://dead-souls.net/example.html ! ! * If you get stuck in the editor type a single dot on ! a blank line, then enter, then Q, then enter, like this: ! ! . ! Q * Admins: there is a new command: admintool *************** *** 21,28 **** you evaluate functions. For example: ------------------------ eval return this_player()->GetName() ! eval find_player("cratylus") ! eval present("sword",find_player("testylus"))->GetClass() ------------------------ --- 27,34 ---- you evaluate functions. For example: ------------------------ eval return this_player()->GetName() ! eval return find_player("cratylus") ! eval return present("sword",find_player("testylus"))->GetClass() ------------------------ *************** *** 89,92 **** /secure directories. You can't read anything in other creators' home dirs. Your read access to some items in the /secure directory is limited. ! If you're admin, of course, you have full access to everything. --- 95,98 ---- /secure directories. You can't read anything in other creators' home dirs. Your read access to some items in the /secure directory is limited. ! If you're full admin, of course, you have full access to everything. diff -c -r --new-file ds2.0r26/lib/news/reminders.txt ds2.0r29/lib/news/reminders.txt *** ds2.0r26/lib/news/reminders.txt Sun Dec 18 12:51:03 2005 --- ds2.0r29/lib/news/reminders.txt Wed Jul 5 00:00:58 2006 *************** *** 38,44 **** Destroy an object: dest example: dest key ! NOTE: Desting players or other creators is extrememly rude. Look in your current directory (your current folder): ls --- 38,44 ---- Destroy an object: dest example: dest key ! NOTE: Desting players or other creators is extremely rude. Look in your current directory (your current folder): ls diff -c -r --new-file ds2.0r26/lib/news/welcome ds2.0r29/lib/news/welcome *** ds2.0r26/lib/news/welcome Sun Jun 18 16:20:59 2006 --- ds2.0r29/lib/news/welcome Wed Jul 5 00:00:58 2006 *************** *** 1,11 **** ! The Dead Souls Object Library ! Version 2 for MudOS v22.2b14 ! Released 18 DEC 2005 by the Frontiers LPC Foundation, ! dedicated to the preservation of Old School Code. ! ! This software is copyrighted and not GPL. ! ! For more info: http://dead-souls.sourceforge.net/ --- 1,6 ---- ! The Dead Souls Object Library version 2 ! This software is copyrighted and not GPL. ! For more info: http://dead-souls.net diff -c -r --new-file ds2.0r26/lib/obj/README ds2.0r29/lib/obj/README *** ds2.0r26/lib/obj/README Wed Dec 7 14:22:44 2005 --- ds2.0r29/lib/obj/README Wed Jul 5 00:00:58 2006 *************** *** 2,4 **** --- 2,12 ---- systems. Removing this directory or its contents, or modifying its contents may generate unexpected behavior from your mud. + + Do not try to use these objects directly, and do not + copy them into your area directories as templates. + QCS uses these rooms in very special ways, and having them + in your area directories may confuse it and give you + errors you don't understand. + + diff -c -r --new-file ds2.0r26/lib/obj/stargate.c ds2.0r29/lib/obj/stargate.c *** ds2.0r26/lib/obj/stargate.c Thu Apr 13 21:14:11 2006 --- ds2.0r29/lib/obj/stargate.c Sun Jul 9 19:04:29 2006 *************** *** 57,72 **** seems, and i need to test some ideas before i can say "do it this way" */ inherit LIB_STARGATE; ! int readScreen(); void create() { ::create(); ! setOrigin("default", "/obj/room"); ! // SetRead(([ ({ "screen" }) : (: readScreen :) ]) ); ! // SetItems(([ ({ "screen" }) : "a computer screen which shows the status of the gate network" ]) ); } void init() --- 57,78 ---- seems, and i need to test some ideas before i can say "do it this way" */ + + #include + #include + #include + #include "/lib/include/stargate.h" + inherit LIB_STARGATE; ! int ReadScreen(); void create() { ::create(); ! SetOrigin("ORIGIN_NAME", "/ORIGIN/GOES/HERE"); ! SetRead(([ ({ "screen" }) : (: ReadScreen :) ]) ); ! SetItems(([ ({ "screen" }) : "a computer screen which shows the status of the gate network" ]) ); } void init() *************** *** 74,80 **** ::init(); } ! int readScreen() { write("stargate network status\n"); write("-----------------------\n"); --- 80,86 ---- ::init(); } ! int ReadScreen() { write("stargate network status\n"); write("-----------------------\n"); diff -c -r --new-file ds2.0r26/lib/obj/stargate.example ds2.0r29/lib/obj/stargate.example *** ds2.0r26/lib/obj/stargate.example Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/obj/stargate.example Sat Jul 8 23:30:59 2006 *************** *** 0 **** --- 1,89 ---- + #include + #include + #include "/lib/include/stargate.h" + + /** + * based on portal.c by Brodbane - March 2006 + * + * $Id: stargate.c,v 1.1 2006/04/05 05:48:39 jam Exp $ + * + * The desired functionality is much like a "star gate": users dialed + * letters or full words that lined up with destinations. A portal opens to + * that destination briefly. To define destinations you must setup a + * constant below then add it to the switch statement in the cmdDial + * function. This object is crude and basic, but gets the job done. + * + * 2006-03-22, jonez + * - original version of this file is from Daelas@Moraelinost + * 2006-03-23, jonez + * - altered so code uses existing verbs (touch, enter) where possible. last add_action is for dial command. + * - added single mapping called "database" and made the "dial" command use it. + * - dial command no longer uses switch/case, making adding a new destination simpler + * - made use of SetPreventGet() / SetPreventPut() + * - made use of new stargate daemon + * - made use of LIB_STARGATE + * - made use of STARGATE_D + * + * IDEAS: + * - create a daemon that holds the stargate network [DONE] + * - allow for stargate failure + * - add dhd object + * - change the code so that it uses a single mapping of names and + * destinations, perhaps in a database file. currently an update to the + * object requires an update for all the objects. [DONE] + * - dhd skill (thanks plato) + * - delay when dialing gate. destination dhd lights up? + * - player should not be able to dial earth if earth is already connected elsewhere (need daemon) [DONE] + * - make use of existing verbs (enter, touch) instead of doing our own thing. [DONE] + * - daemon should contain a class that maps the various gates to each other. see lib/include/door.h [DONE] + * - shout "off world activation" into the gateroom when the gate engages. + * - track status as "incoming" or "outgoing".. you can only "enter" an outgoing gate (rhk) [DONE] + * - if room is empty, shut down the gate (rhk) + * - change callout time when someone goes through the gate (rhk) + */ + + /* + Cratylus@Dead Souls but let me give you a quick outline + Cratylus@Dead Souls i type dial thing + Cratylus@Dead Souls the thing inherits LIB_DIAL + Cratylus@Dead Souls which is in /lib/events/dial.c + Cratylus@Dead Souls and all that contains is like direct_dial_ob() return 1; this kind of thing + Cratylus@Dead Souls take a look at LIB_TURN + Cratylus@Dead Souls what LIB_DIAL does is provide the object with hooks, so it *can* be dialed + Cratylus@Dead Souls so, when i type dial thing, the thing goes, yeah i + can be dialed, and then the parser enters the can_dial and do_dial funcs + in the verb + Cratylus@Dead Souls tellya what. i'd like to work with you on this one. i think it's less straightforward than it + seems, and i need to test some ideas before i can say "do it this way" + + */ + + #include + #include + #include + #include "/lib/include/stargate.h" + + inherit LIB_STARGATE; + + int ReadScreen(); + + void create() + { + ::create(); + SetOrigin("ORIGIN_NAME", "/ORIGIN/GOES/HERE"); + SetRead(([ ({ "screen" }) : (: ReadScreen :) ]) ); + SetItems(([ ({ "screen" }) : "a computer screen which shows the status of the gate network" ]) ); + } + + void init() + { + ::init(); + } + + int ReadScreen() + { + write("stargate network status\n"); + write("-----------------------\n"); + write("\n"); + + } diff -c -r --new-file ds2.0r26/lib/realms/template/area/obj/table.c ds2.0r29/lib/realms/template/area/obj/table.c *** ds2.0r26/lib/realms/template/area/obj/table.c Wed Apr 5 19:50:53 2006 --- ds2.0r29/lib/realms/template/area/obj/table.c Sat Jul 8 23:30:59 2006 *************** *** 15,22 **** SetMaxCarry(5000); SetInventory( ([ MY_OBJ "/key" : 1, ]) ); } void init(){ ::init(); ! } \ No newline at end of file --- 15,23 ---- SetMaxCarry(5000); SetInventory( ([ MY_OBJ "/key" : 1, + "/secure/obj/glasses" :1, ]) ); } void init(){ ::init(); ! } diff -c -r --new-file ds2.0r26/lib/realms/template/workroom.c ds2.0r29/lib/realms/template/workroom.c *** ds2.0r26/lib/realms/template/workroom.c Sun Dec 18 01:57:11 2005 --- ds2.0r29/lib/realms/template/workroom.c Wed Jul 5 00:01:05 2006 *************** *** 31,43 **** ]) ); SetInventory( ([ "/domains/default/obj/chest" : 1, ! "/domains/default/obj/bbucket" :1, ]) ); - SetObviousExits("e,d"); SetExits( ([ "down" : "/domains/default/room/wiz_hall.c", "east" : MY_ROOM "/sample_room" ]) ); ! SetNoModify(1); } int ReadSign(){ --- 31,42 ---- ]) ); SetInventory( ([ "/domains/default/obj/chest" : 1, ! "/domains/default/obj/bbucket" :1, ]) ); SetExits( ([ "down" : "/domains/default/room/wiz_hall.c", "east" : MY_ROOM "/sample_room" ]) ); ! SetNoModify(0); } int ReadSign(){ diff -c -r --new-file ds2.0r26/lib/save/events.o ds2.0r29/lib/save/events.o *** ds2.0r26/lib/save/events.o Sun Jun 18 16:20:59 2006 --- ds2.0r29/lib/save/events.o Wed Jul 5 00:00:58 2006 *************** *** 1,3 **** #/secure/daemon/events.c RebootInterval 1000 ! Events ([1150663330:(["function":"RotateLogs","interval":7200,"args":({}),"object":"/secure/daemon/log","creator":"/secure/daemon/log","regular":7200,]),]) --- 1,3 ---- #/secure/daemon/events.c RebootInterval 1000 ! Events ([1151333254:(["interval":7200,"args":({}),"object":"/secure/daemon/log","function":"RotateLogs","regular":7200,"creator":"/secure/daemon/log",]),]) diff -c -r --new-file ds2.0r26/lib/secure/cmds/admins/addrace.c ds2.0r29/lib/secure/cmds/admins/addrace.c *** ds2.0r26/lib/secure/cmds/admins/addrace.c Mon Nov 7 13:32:16 2005 --- ds2.0r29/lib/secure/cmds/admins/addrace.c Wed Jul 5 00:01:12 2006 *************** *** 35,57 **** "races daemon. The optional second argument specifies if this " "race is a player or not. If it is omitted or it is 0, the race " "is assumed to be NPC-only. If it is 1, then it is assumed to " ! "be useable by players as well.\n" ! "The format of the file being read is:\n" ! "race_name\n" ! "min_light_sensitivity:max_light_sensitivity\n" ! "language\n" ! "resistance1:resistance_level1\n" ! "...\n" ! "resistanceN:resistance_levelN\n" ! "stat1:stat_average1:stat_class1\n" ! "...\n" ! "statN:stat_averageN:stat_classN\n" ! "limb1:limb_parent1:limb_class1:limb_armors_list1\n" ! "...\n" ! "limbN:limb_parentN:limb_classN:limb_armors_listN\n" ! "fingered_limb1:num_fingers1\n" ! "...\n" ! "fingered_limbN:num_fingersN\n\n" "An example of a human exists in /secure/cfg/races/human. " "You will notice that a human hs no special resistances. The " "number of times resistances, stats, limbs, and fingers appear " --- 35,44 ---- "races daemon. The optional second argument specifies if this " "race is a player or not. If it is omitted or it is 0, the race " "is assumed to be NPC-only. If it is 1, then it is assumed to " ! "be usable by players as well.\n" ! "NOTE: The PLAYER_RACE setting in the race file overrides that flag.\n" ! "The format of the file is explained here:\n" ! "http://dead-souls.net/ds-creator-faq.html#2.45\n\n" "An example of a human exists in /secure/cfg/races/human. " "You will notice that a human hs no special resistances. The " "number of times resistances, stats, limbs, and fingers appear " *************** *** 61,68 **** "For example, the right hand may come any time after the right " "arm, but it must come after the right arm.\n" "This system is admittedly rather complex, but it beats hard " ! "coding these values. In addition, a web-based administration " ! "client is being developed to make race creation nothing more " ! "than filling in a form.\n\n" "See also: addclass, addemote"); } --- 48,53 ---- "For example, the right hand may come any time after the right " "arm, but it must come after the right arm.\n" "This system is admittedly rather complex, but it beats hard " ! "coding these values.\n\n" "See also: addclass, addemote"); } diff -c -r --new-file ds2.0r26/lib/secure/cmds/admins/admintool.c ds2.0r29/lib/secure/cmds/admins/admintool.c *** ds2.0r26/lib/secure/cmds/admins/admintool.c Sun Jun 18 16:21:00 2006 --- ds2.0r29/lib/secure/cmds/admins/admintool.c Wed Jul 5 00:01:12 2006 *************** *** 6,12 **** inherit LIB_DAEMON; static private void validate() { ! if( !((int)master()->valid_apply(({ "PRIV_ASSIST", "PRIV_SECURE" }))) ) error("Illegal attempt to access admintool: "+get_stack()+" "+identify(previous_object(-1))); } --- 6,13 ---- inherit LIB_DAEMON; static private void validate() { ! if(!this_player()) return 0; ! if( !((int)master()->valid_apply(({ "ASSIST" }))) ) error("Illegal attempt to access admintool: "+get_stack()+" "+identify(previous_object(-1))); } *************** *** 1223,1229 **** --- 1224,1243 ---- str = global_group_temp; global_group_temp = ""; + + if(str == "ASSIST" || str == "SECURE" ) { + if(!securep(this_player())){ + write("Only full admins may do this."); + Menu(); + return 1; + } + } + + //tc("str: "+str); + //tc("green","green"); + if(str == "SECURE"){ + validate(); if(!members || members == "") { write("You're not leaving the SECURE group empty. Modification cancelled.\n"); Menu(); diff -c -r --new-file ds2.0r26/lib/secure/cmds/admins/decre.c ds2.0r29/lib/secure/cmds/admins/decre.c *** ds2.0r26/lib/secure/cmds/admins/decre.c Sun Jun 18 18:00:27 2006 --- ds2.0r29/lib/secure/cmds/admins/decre.c Wed Jul 5 00:01:12 2006 *************** *** 5,10 **** --- 5,11 ---- */ #include + #include #include #include *************** *** 17,24 **** object *inv; string nom, file; ! if( !((int)master()->valid_apply(({ "PRIV_ASSIST", "PRIV_SECURE", "LIB_CONNECT" }))) ) ! error("Illegal decre attempt: "+get_stack()+" "+identify(previous_object(-1))); if( args == "" || !stringp(args) ) return "Who do you want to make a player?"; --- 18,25 ---- object *inv; string nom, file; ! if( !((int)master()->valid_apply(({ PRIV_ASSIST, PRIV_SECURE, LIB_CONNECT }))) ) ! error("Illegal decre attempt: "+get_stack()+" "+identify(previous_object(-1))); if( args == "" || !stringp(args) ) return "Who do you want to make a player?"; diff -c -r --new-file ds2.0r26/lib/secure/cmds/admins/encre.c ds2.0r29/lib/secure/cmds/admins/encre.c *** ds2.0r26/lib/secure/cmds/admins/encre.c Sun Jun 18 18:00:27 2006 --- ds2.0r29/lib/secure/cmds/admins/encre.c Wed Jul 5 00:01:12 2006 *************** *** 4,9 **** --- 4,10 ---- */ #include + #include #include #include *************** *** 15,22 **** object ob, cre_ob, jeans, shirt, robe, hat, book, staff; string file, nom; ! if( !((int)master()->valid_apply(({ "PRIV_ASSIST", "PRIV_SECURE", "LIB_CONNECT" }))) ) ! error("Illegal encre attempt: "+get_stack()+" "+identify(previous_object(-1))); if( args == "" || !stringp(args) ) return "Who do you want to make a creator?"; --- 16,23 ---- object ob, cre_ob, jeans, shirt, robe, hat, book, staff; string file, nom; ! if( !((int)master()->valid_apply(({ PRIV_ASSIST, PRIV_SECURE, LIB_CONNECT }))) ) ! error("Illegal encre attempt: "+get_stack()+" "+identify(previous_object(-1))); if( args == "" || !stringp(args) ) return "Who do you want to make a creator?"; diff -c -r --new-file ds2.0r26/lib/secure/cmds/admins/setreboot.c ds2.0r29/lib/secure/cmds/admins/setreboot.c *** ds2.0r26/lib/secure/cmds/admins/setreboot.c Mon Nov 7 13:32:16 2005 --- ds2.0r29/lib/secure/cmds/admins/setreboot.c Wed Jul 5 00:01:12 2006 *************** *** 6,13 **** int cmd(string str) { int x; ! if(!str || !archp(previous_object())) return 0; ! sscanf(str, "%d", x); x = (int)EVENTS_D->SetRebootInterval(x); message("info", "Reboot interval set to "+x+" hours.", this_player()); return 1; --- 6,18 ---- int cmd(string str) { int x; ! if( !((int)master()->valid_apply(({ "ASSIST" }))) ){ ! return 0; ! } ! ! if(!str || str == "" || !sscanf(str, "%d", x)){ ! this_object()->help(); ! } x = (int)EVENTS_D->SetRebootInterval(x); message("info", "Reboot interval set to "+x+" hours.", this_player()); return 1; diff -c -r --new-file ds2.0r26/lib/secure/cmds/admins/snoopreport.c ds2.0r29/lib/secure/cmds/admins/snoopreport.c *** ds2.0r26/lib/secure/cmds/admins/snoopreport.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/secure/cmds/admins/snoopreport.c Wed Jul 5 19:58:20 2006 *************** *** 0 **** --- 1,16 ---- + // This command is only useful if you own an intermud channel + + #include + #include + + inherit LIB_DAEMON; + + mixed cmd(string args) { + string chan, mud; + + if(!this_player() || !archp(this_player())) return 0; + + SNOOP_D->Report(); + + return 1; + } diff -c -r --new-file ds2.0r26/lib/secure/cmds/admins/switchrouter.c ds2.0r29/lib/secure/cmds/admins/switchrouter.c *** ds2.0r26/lib/secure/cmds/admins/switchrouter.c Sun Jun 18 16:21:03 2006 --- ds2.0r29/lib/secure/cmds/admins/switchrouter.c Wed Jul 5 00:01:12 2006 *************** *** 11,21 **** if(!archp(previous_object())) return "No."; if(find_object(INTERMUD_D))find_object(INTERMUD_D)->eventDestruct(); ! rm("/save/intermud.o"); if(!args || args == ""){ ! write("No argument provided. Reloading intermud daemon."); if( load_object(INTERMUD_D) ) write("Intermud daemon reloaded."); else write("Failed to reload intermud daemon."); return 1; --- 11,22 ---- if(!archp(previous_object())) return "No."; + if(find_object(INTERMUD_D))find_object(INTERMUD_D)->eventClearVars(); if(find_object(INTERMUD_D))find_object(INTERMUD_D)->eventDestruct(); ! //rm("/save/intermud.o"); if(!args || args == ""){ ! write("Reloading intermud daemon."); if( load_object(INTERMUD_D) ) write("Intermud daemon reloaded."); else write("Failed to reload intermud daemon."); return 1; diff -c -r --new-file ds2.0r26/lib/secure/cmds/creators/about.c ds2.0r29/lib/secure/cmds/creators/about.c *** ds2.0r26/lib/secure/cmds/creators/about.c Wed Jan 4 20:42:56 2006 --- ds2.0r29/lib/secure/cmds/creators/about.c Wed Jul 5 00:01:12 2006 *************** *** 21,26 **** --- 21,32 ---- if(!thing) thing = present(str, environment(this_player())); if(thing->GetDoor()) thing = load_object(thing->GetDoor()); if(!thing) return notify_fail("Uh oh, error.\n"); + if(interactive(thing)){ + message( "info","Players do not have files with LPC code. " + "Player save files are not subject to examination with this command.", + this_player()); + return 1; + } name = base_name(thing) + ".c"; message( "info", name + "\n", this_player() ); return (mixed)this_player()->eventPage(name, MSG_SYSTEM | MSG_NOCOLOUR); diff -c -r --new-file ds2.0r26/lib/secure/cmds/creators/ed.c ds2.0r29/lib/secure/cmds/creators/ed.c *** ds2.0r26/lib/secure/cmds/creators/ed.c Sat Mar 11 11:16:59 2006 --- ds2.0r29/lib/secure/cmds/creators/ed.c Wed Jul 5 00:01:12 2006 *************** *** 18,23 **** --- 18,31 ---- identify(previous_object(-1)), this_player()); return 0; } + + if(!this_player()->GetProperty("EdWarned")){ + write("This is the first time you've used ed. If you get stuck, simply " + "hit return a few times, then enter a dot on a blank line, hit return, " + "then type Q, then enter. Then visit this page to learn more about " + "using the ed editor: http://dead-souls.net/editor.html"); + this_player()->SetProperty("EdWarned", 1); + } args = absolute_path( (string)this_player()->query_cwd(), args ); if( (x = file_size(args)) == -2 ) return "You cannot edit a directory!"; diff -c -r --new-file ds2.0r26/lib/secure/cmds/creators/eval.c ds2.0r29/lib/secure/cmds/creators/eval.c *** ds2.0r26/lib/secure/cmds/creators/eval.c Wed Apr 12 23:49:46 2006 --- ds2.0r29/lib/secure/cmds/creators/eval.c Wed Jul 5 00:01:12 2006 *************** *** 49,64 **** } filename += "CMD_EVAL_TMP_FILE.c"; if(securep(previous_object())) filename = "/secure/tmp/"+previous_object()->GetKeyName()+"_CMD_EVAL_TMP_FILE.c"; // long name so won't coincide with file already in your directory by accident rm( filename ); if( ret = find_object( filename ) ) destruct( ret ); ! write_file( filename, file ); // if( err = catch( ret = (mixed)call_other( filename, "eval" ) ) ) // write( "Error = " + err ); // else ret = (mixed)call_other(filename, "eval"); write( wrap( "Result = " + identify( ret ) ) ); ! rm( filename ); if( ret = find_object( filename ) ) destruct( ret ); // Some muds prefer to change these lines so filename isn't deleted if --- 49,66 ---- } filename += "CMD_EVAL_TMP_FILE.c"; if(securep(previous_object())) filename = "/secure/tmp/"+previous_object()->GetKeyName()+"_CMD_EVAL_TMP_FILE.c"; + //tc("filename: "+filename); + //tc("previous_object: "+identify(previous_object())); // long name so won't coincide with file already in your directory by accident rm( filename ); if( ret = find_object( filename ) ) destruct( ret ); ! write_file( filename, file,1 ); // if( err = catch( ret = (mixed)call_other( filename, "eval" ) ) ) // write( "Error = " + err ); // else ret = (mixed)call_other(filename, "eval"); write( wrap( "Result = " + identify( ret ) ) ); ! //rm( filename ); if( ret = find_object( filename ) ) destruct( ret ); // Some muds prefer to change these lines so filename isn't deleted if diff -c -r --new-file ds2.0r26/lib/secure/cmds/creators/force.c ds2.0r29/lib/secure/cmds/creators/force.c *** ds2.0r26/lib/secure/cmds/creators/force.c Mon Jan 23 08:56:34 2006 --- ds2.0r29/lib/secure/cmds/creators/force.c Wed Dec 31 19:00:00 1969 *************** *** 1,53 **** - /* /cmds/creators/force.c - * From the Dead Souls V Object Library - * Created by Descartes of Borg 961018 - * Version: %A% - * Last modified: %D% - */ - - #include - - inherit LIB_DAEMON; - - mixed cmd(string args) { - object who = previous_object(); - object target; - string name, cmd; - - if(!args || args==""){ - who->eventPrint("Force whom to do what?"); - return 1; - } - if( sscanf(args, "%s to %s", name, cmd) < 1 ) { - if(sscanf(args, "%s %s", name,cmd) < 1) { - who->eventPrint("Force whom to do what?"); - return 1; - } - } - target = present(lower_case(name),environment(who)); - if( !target ) { - who->eventPrint("Cannot find any living thing called: " + name); - return 1; - } - if(archp(target) && !archp(who)){ - who->eventPrint(target->GetName()+" shakes "+possessive(target)+ - " head and forces you to dest yourself."); - tell_room(environment(who), who->GetName()+" dests "+objective(who)+ - "self while trying to pull a foolish joke on "+target->GetName()+".", who); - who->eventDestruct(); - return 1; - } - target->eventPrint(who->GetName() + " forces you to: " + cmd); - who->eventPrint("You force " + target->GetShort() + " to: " + cmd); - target->eventForce(cmd); - return 1; - } - - string GetErorMessage() { - return "Force whom to do what?"; - } - - string GetHelp() { - return ("Syntax: \n\n" - "Allows you to force a living object to take a certain action."); - } --- 0 ---- diff -c -r --new-file ds2.0r26/lib/secure/cmds/creators/mv.c ds2.0r29/lib/secure/cmds/creators/mv.c *** ds2.0r26/lib/secure/cmds/creators/mv.c Mon Nov 7 13:32:17 2005 --- ds2.0r29/lib/secure/cmds/creators/mv.c Wed Jul 5 00:01:12 2006 *************** *** 23,35 **** /* We should add checks for flags here. */ return help(); } else { ! #if 0 if(file_size(t2=absolute_path((string)this_player()->query_cwd(),t2)) > 0) { notify_fail("mv: "+t2+" already exists.\n"); return 0; } ! #endif t2=absolute_path((string)this_player()->query_cwd(),t2); rename(t1=absolute_path(this_player()->query_cwd(),t1),t2); if(file_size(t2) == -2) { --- 23,35 ---- /* We should add checks for flags here. */ return help(); } else { ! //#if 0 if(file_size(t2=absolute_path((string)this_player()->query_cwd(),t2)) > 0) { notify_fail("mv: "+t2+" already exists.\n"); return 0; } ! //#endif t2=absolute_path((string)this_player()->query_cwd(),t2); rename(t1=absolute_path(this_player()->query_cwd(),t1),t2); if(file_size(t2) == -2) { diff -c -r --new-file ds2.0r26/lib/secure/cmds/players/tell.c ds2.0r29/lib/secure/cmds/players/tell.c *** ds2.0r26/lib/secure/cmds/players/tell.c Sun Jun 18 16:21:05 2006 --- ds2.0r29/lib/secure/cmds/players/tell.c Wed Jul 5 00:01:12 2006 *************** *** 15,21 **** mixed mud; object ob, machine; int i, maxi; ! string who, msg, tmp, machine_message; if(!str) return notify_fail("Syntax: \n"); if(!creatorp(this_player()) && this_player()->GetMagicPoints() < 15) { --- 15,21 ---- mixed mud; object ob, machine; int i, maxi; ! string who, msg, tmp, tmp2, machine_message; if(!str) return notify_fail("Syntax: \n"); if(!creatorp(this_player()) && this_player()->GetMagicPoints() < 15) { *************** *** 29,36 **** maxi = sizeof(words = explode(words[1], " ")); for(i=0; iGetMudName(tmp) ) { mud = tmp; if(i+1 < maxi) msg = implode(words[i+1..maxi-1], " "); else msg = ""; --- 29,38 ---- maxi = sizeof(words = explode(words[1], " ")); for(i=0; iGetMudName(tmp) ! && !((string)INTERMUD_D->GetMudName(tmp2)) ) { mud = tmp; if(i+1 < maxi) msg = implode(words[i+1..maxi-1], " "); else msg = ""; diff -c -r --new-file ds2.0r26/lib/secure/daemon/bboard.c ds2.0r29/lib/secure/daemon/bboard.c *** ds2.0r26/lib/secure/daemon/bboard.c Mon Jan 16 23:03:39 2006 --- ds2.0r29/lib/secure/daemon/bboard.c Wed Jul 5 19:58:20 2006 *************** *** 49,56 **** static private int valid_access() { string str; ! ! if(__Owner == PRIV_SECURE && !((int)master()->valid_access(({})))) return 0; str = query_privs(previous_object(0)); if(member_array(PRIV_SECURE, explode(str, ":")) != -1) return 1; --- 49,56 ---- static private int valid_access() { string str; ! if(this_player() && archp(this_player())) true(); ! else if(__Owner == PRIV_SECURE && !((int)master()->valid_apply(({})))) return 0; str = query_privs(previous_object(0)); if(member_array(PRIV_SECURE, explode(str, ":")) != -1) return 1; diff -c -r --new-file ds2.0r26/lib/secure/daemon/chat.c ds2.0r29/lib/secure/daemon/chat.c *** ds2.0r26/lib/secure/daemon/chat.c Sun Jun 18 16:21:05 2006 --- ds2.0r29/lib/secure/daemon/chat.c Sun Jul 9 19:04:29 2006 *************** *** 131,136 **** --- 131,137 ---- if(pmsg) plainmsg += pmsg; if(pwho && pwho !="") plainmsg = pwho+" "+plainmsg; if(pchan && pchan != "admin"){ + chan = GetLocalChannel(chan); unguarded( (: write_file("/log/chan/"+chan,"["+timestamp()+"] "+plainmsg+"\n") :) ); if( file_size("/log/chan/"+chan) > 200000) { unguarded( (: rename("/log/chan/"+chan,"/log/chan/"+chan+"."+timestamp() ) :) ); *************** *** 150,156 **** object ob = 0; int emote; ! if(first(str,1) == ":" && sizeof(str) > 3){ if(!grepp(verb,"emote")) verb += "emote"; str = trim(replace_string(str,":","",1)); } --- 151,159 ---- object ob = 0; int emote; ! if(first(str,1) == ":" && ! (member_array(str[1..1], ({ "Q", "O", "P", "D", "I", "X" })) == -1 && ! alphap(str[1..1]) && sizeof(str) > 3)){ if(!grepp(verb,"emote")) verb += "emote"; str = trim(replace_string(str,":","",1)); } *************** *** 170,182 **** string *who; string ch, mud; ! if( !str ) return 0; if( sscanf(str, "%s@%s", ch, mud) == 2 ) { mud = trim(mud); if(!alphap(last(mud,1))) mud = truncate(mud,1); ! if( !Channels[ch] ) return 0; ! if( member_array(this_player(), Channels[ch]) == -1 ) return 0; ! if( ch == (ch = GetRemoteChannel(ch)) ) return 0; if( !(mud = (string)INTERMUD_D->GetMudName(mud)) ) { this_player()->eventPrint(mud_name() + " is not aware of " "such a place.", MSG_ERROR); --- 173,196 ---- string *who; string ch, mud; ! if( !str ) { ! return 0; ! } if( sscanf(str, "%s@%s", ch, mud) == 2 ) { mud = trim(mud); if(!alphap(last(mud,1))) mud = truncate(mud,1); ! if( !Channels[ch] ) { ! return 0; ! } ! if( member_array(this_player(), Channels[ch]) == -1 ) { ! return 0; ! } ! if( ch == (ch = GetRemoteChannel(ch)) ) { ! if(!creatorp(this_player())){ ! write("Remote channel information is not available to players."); ! return 1; ! } ! } if( !(mud = (string)INTERMUD_D->GetMudName(mud)) ) { this_player()->eventPrint(mud_name() + " is not aware of " "such a place.", MSG_ERROR); *************** *** 192,199 **** return 1; } else ch = str; ! if( !Channels[ch] ) return 0; ! if( member_array(this_player(), Channels[str]) == -1 ) return 0; who = GetChannelList(str); msg = "Online: " + implode(who, " "); //tc("msg1"); --- 206,217 ---- return 1; } else ch = str; ! if( !Channels[ch] ) { ! return 0; ! } ! if( member_array(this_player(), Channels[str]) == -1 ) { ! return 0; ! } who = GetChannelList(str); msg = "Online: " + implode(who, " "); //tc("msg1"); diff -c -r --new-file ds2.0r26/lib/secure/daemon/finger.c ds2.0r29/lib/secure/daemon/finger.c *** ds2.0r26/lib/secure/daemon/finger.c Wed Apr 12 23:50:02 2006 --- ds2.0r29/lib/secure/daemon/finger.c Fri Jul 7 19:41:43 2006 *************** *** 128,134 **** else ret += "On since " + ctime(LoginTime); } else ret += "Last on " + ctime(LoginTime); ! if( !WhereBlock || (this_player(1) && archp(this_player(1))) ) ret += " from " + HostSite + "%^BR%^\n"; else ret += "%^BR%^\n"; mail_stat = (mapping)FOLDERS_D->mail_status(who); --- 128,134 ---- else ret += "On since " + ctime(LoginTime); } else ret += "Last on " + ctime(LoginTime); ! if( this_player(1) && creatorp(this_player(1)) ) ret += " from " + HostSite + "%^BR%^\n"; else ret += "%^BR%^\n"; mail_stat = (mapping)FOLDERS_D->mail_status(who); *************** *** 173,179 **** } if( !Email ) Email = "#CHANGE"; tmp = ({ CapName, GetTitle(), RealName, (Email[0] != '#' ? Email : 0), ! ctime(LoginTime), (ob && interactive(ob) ? query_idle(ob) : -1), 0, (creator ? "Creator" : "" + Level), plan }); return tmp; } --- 173,179 ---- } if( !Email ) Email = "#CHANGE"; tmp = ({ CapName, GetTitle(), RealName, (Email[0] != '#' ? Email : 0), ! ctime(LoginTime), ((ob && interactive(ob) && !(ob->GetInvis())) ? query_idle(ob) : -1), 0, (creator ? "Creator" : "" + Level), plan }); return tmp; } diff -c -r --new-file ds2.0r26/lib/secure/daemon/folders.c ds2.0r29/lib/secure/daemon/folders.c *** ds2.0r26/lib/secure/daemon/folders.c Mon Nov 7 13:32:07 2005 --- ds2.0r29/lib/secure/daemon/folders.c Wed Jul 5 00:01:05 2006 *************** *** 85,91 **** if(folder != "new") return; if((pl=find_player(who)) && (int)OPTIONS_D->query_option(who, "notify")) { msg = (string)OPTIONS_D->query_option(who, "message"); ! if( !stringp(msg) ) msg = "New mail from $N!!!\n"; msg = replace_string(replace_string(msg, "$S", borg["subject"]), "$N", capitalize(borg["from"])); message("system", msg, pl); --- 85,91 ---- if(folder != "new") return; if((pl=find_player(who)) && (int)OPTIONS_D->query_option(who, "notify")) { msg = (string)OPTIONS_D->query_option(who, "message"); ! if( !stringp(msg) ) msg = "New mail from $N!\n"; msg = replace_string(replace_string(msg, "$S", borg["subject"]), "$N", capitalize(borg["from"])); message("system", msg, pl); diff -c -r --new-file ds2.0r26/lib/secure/daemon/i3router/core_stuff.h ds2.0r29/lib/secure/daemon/i3router/core_stuff.h *** ds2.0r26/lib/secure/daemon/i3router/core_stuff.h Sun Apr 9 23:51:25 2006 --- ds2.0r29/lib/secure/daemon/i3router/core_stuff.h Wed Jul 5 00:01:12 2006 *************** *** 1,9 **** // This file written completely by Tim Johnson (Tim@TimMUD) #include static void create(){ SetNoClean(1); - //save::create(); sockets = ([]); connected_muds = ([]); if(!mudinfo) mudinfo = ([]); --- 1,9 ---- // This file written completely by Tim Johnson (Tim@TimMUD) #include + #include static void create(){ SetNoClean(1); sockets = ([]); connected_muds = ([]); if(!mudinfo) mudinfo = ([]); *************** *** 13,24 **** if(!channels) channels = ([]); if(!channel_updates) channel_updates = ([]); if(!channel_update_counter) channel_update_counter = 1; ! if(!router_name) router_name = "*test"; ! //if(!router_list) router_list = ({ ({"*yatmim", "149.152.218.102 23"}) }); ! if(!router_list) router_list = ({ ({"*test", "192.168.0.201 9000"}) }); log_file("server", "Created when uptime = " + uptime() + "\n"); trr("server got created"); call_out("setup", 5); set_heart_beat(10); } --- 13,25 ---- if(!channels) channels = ([]); if(!channel_updates) channel_updates = ([]); if(!channel_update_counter) channel_update_counter = 1; ! if(!router_name) router_name = "*crossing"; ! router_list = ({ ({"*crossing", "192.168.0.5 9000"}) }); log_file("server", "Created when uptime = " + uptime() + "\n"); trr("server got created"); + log_file("i3router",timestamp()+" router object created."); call_out("setup", 5); + call_out("LocalHostedChans", 15); set_heart_beat(10); } *************** *** 30,35 **** --- 31,38 ---- static void setup(){ trr("setup got called"); + if( file_size( SAVE_ROUTER __SAVE_EXTENSION__ ) > 0 ) + unguarded( (: restore_object, SAVE_ROUTER, 1 :) ); if ((router_socket = socket_create(MUD, "read_callback", "close_callback")) < 0){ log_file("server", "setup: Failed to create socket.\n"); trr("setup: Failed to create socket.\n"); *************** *** 52,58 **** void remove(){ string mudname; log_file("server", "Being removed by: "+identify(previous_object())+"\n"); ! trr("Being removed by: "+identify(previous_object())+"\n"); log_file("server", "sockets:"+identify(sockets)+"\n"); trr("sockets:"+identify(sockets)+"\n"); log_file("server", "Starting to destruct at uptime = " + uptime() + "\n"); --- 55,61 ---- void remove(){ string mudname; log_file("server", "Being removed by: "+identify(previous_object())+"\n"); ! trr("Being removed by: "+identify(previous_object())+"\n","red"); log_file("server", "sockets:"+identify(sockets)+"\n"); trr("sockets:"+identify(sockets)+"\n"); log_file("server", "Starting to destruct at uptime = " + uptime() + "\n"); diff -c -r --new-file ds2.0r26/lib/secure/daemon/i3router/hosted_channels.h ds2.0r29/lib/secure/daemon/i3router/hosted_channels.h *** ds2.0r26/lib/secure/daemon/i3router/hosted_channels.h Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/secure/daemon/i3router/hosted_channels.h Wed Jul 5 00:01:12 2006 *************** *** 0 **** --- 1,27 ---- + int LocalHostedChans(){ + process_channel(1, ({ "channel-add", 5, + mud_name(), "cratylus", + "yatmim", 0, "dead_souls", 0 }) ); + + process_channel(1, ({ "channel-add", 5, + mud_name(), "cratylus", + "yatmim", 0, "dead_test4", 0 }) ); + + //process_channel(1, ({ "channel-add", 5, + //mud_name(), "cratylus", + //"yatmim", 0, "dead_test5", 0 }) ); + + process_channel(1, ({ "channel-add", 5, + mud_name(), "cratylus", + "yatmim", 0, "imud_gossip", 0 }) ); + + process_channel(1, ({ "channel-add", 5, + mud_name(), "cratylus", + "yatmim", 0, "imud_code", 0 }) ); + + process_channel(1, ({ "channel-add", 5, + "LPUni Outpost", "tacitus", + "yatmim", 0, "lpuni", 0 }) ); + + return 1; + } diff -c -r --new-file ds2.0r26/lib/secure/daemon/i3router/process_channel.h ds2.0r29/lib/secure/daemon/i3router/process_channel.h *** ds2.0r26/lib/secure/daemon/i3router/process_channel.h Sun Apr 9 23:51:25 2006 --- ds2.0r29/lib/secure/daemon/i3router/process_channel.h Wed Jul 5 00:01:12 2006 *************** *** 1,4 **** --- 1,5 ---- // This file written completely by Tim Johnson (Tim@TimMUD) + #include static void process_channel(int fd, mixed *info){ string mudname; *************** *** 14,20 **** // ignore the target and save some CPU. // Check if string parts are strings... if(info[0][8..]=="t"){ ! if(sizeof(info)!=12 || !stringp(info[9]) || !stringp(info[10]) || !stringp(info[11]) || !stringp(info[12])){ send_error(info[2],info[3],"bad-pkt","Bad packet format.",info); return; --- 15,21 ---- // ignore the target and save some CPU. // Check if string parts are strings... if(info[0][8..]=="t"){ ! if(sizeof(info)!=13 || !stringp(info[9]) || !stringp(info[10]) || !stringp(info[11]) || !stringp(info[12])){ send_error(info[2],info[3],"bad-pkt","Bad packet format.",info); return; *************** *** 107,113 **** channel_update_counter++; channels[info[6]]=({ info[7], info[2], ({}) }); channel_updates[info[6]] = channel_update_counter; ! trr(info[3]+"@"+info[2]+" created the channel: "+info[6]); // broadcast an update saying that this channel is added or changed now // chanlist-reply packet to everybody (who has a channel service?) broadcast_chanlist(info[6]); --- 108,114 ---- channel_update_counter++; channels[info[6]]=({ info[7], info[2], ({}) }); channel_updates[info[6]] = channel_update_counter; ! trr(info[3]+"@"+info[2]+" created the channel: "+info[6],"yellow"); // broadcast an update saying that this channel is added or changed now // chanlist-reply packet to everybody (who has a channel service?) broadcast_chanlist(info[6]); *************** *** 123,128 **** --- 124,130 ---- // 0, channel_update_counter, // ([ info[6]:({ info[2], info[7] }) ]) // })); + save_object(SAVE_ROUTER); return; case "remove": if(!channels[info[6]]){ // error, channel is not registered! *************** *** 139,146 **** channel_update_counter++; map_delete(channels,info[6]); channel_updates[info[6]] = channel_update_counter; ! trr(info[3]+"@"+info[2]+" deleted the channel: "+info[6]); // broadcast an update saying that this channel is gone now return; case "admin": // add/delete muds from the 2 lists... --- 141,149 ---- channel_update_counter++; map_delete(channels,info[6]); channel_updates[info[6]] = channel_update_counter; ! trr(info[3]+"@"+info[2]+" deleted the channel: "+info[6],"yellow"); // broadcast an update saying that this channel is gone now + save_object(SAVE_ROUTER); return; case "admin": // add/delete muds from the 2 lists... *************** *** 159,164 **** --- 162,168 ---- // if removed from allow list, unlisten... listening[info[6]] -= info[8]; } + save_object(SAVE_ROUTER); return; case "listen": // mudname=info[2], channame=info[6], on_or_off=info[7] if(!channels[info[6]]){ // error, channel is not registered! *************** *** 184,189 **** --- 188,194 ---- // in list, you're banned... send_error(info[2],0,"not-allowed", "Banned from "+info[6],info); + save_object(SAVE_ROUTER); return; } // not in ban list at this point *************** *** 191,196 **** --- 196,202 ---- listening[info[6]] += ({ info[2] }); else listening[info[6]] -= ({ info[2] }); + save_object(SAVE_ROUTER); return; case 1: // selectively allowed if(member_array(info[2],channels[info[6]][2])==-1 && *************** *** 205,210 **** --- 211,217 ---- listening[info[6]] += ({ info[2] }); else listening[info[6]] -= ({ info[2] }); + save_object(SAVE_ROUTER); return; case 2: // filtered... act like selectively allowed if(member_array(info[2],channels[info[6]][2])==-1 && *************** *** 220,231 **** listening[info[6]] += ({ info[2] }); else listening[info[6]] -= ({ info[2] }); return; } // switch default: // trying to do "channel-blah" send_error(info[2],info[3],"unk-type","I don't know what "+info[0]+ " means.",info); ! trr("Don't know what the ["+info[0]+"] packet means.", DEB_INVALID); return; } trr("can't get here?"); --- 227,239 ---- listening[info[6]] += ({ info[2] }); else listening[info[6]] -= ({ info[2] }); + save_object(SAVE_ROUTER); return; } // switch default: // trying to do "channel-blah" send_error(info[2],info[3],"unk-type","I don't know what "+info[0]+ " means.",info); ! trr("Don't know what the ["+info[0]+"] packet means.", "yellow"); return; } trr("can't get here?"); diff -c -r --new-file ds2.0r26/lib/secure/daemon/i3router/process_startup_req.h ds2.0r29/lib/secure/daemon/i3router/process_startup_req.h *** ds2.0r26/lib/secure/daemon/i3router/process_startup_req.h Sun Apr 9 23:51:25 2006 --- ds2.0r29/lib/secure/daemon/i3router/process_startup_req.h Wed Jul 5 00:01:12 2006 *************** *** 1,5 **** --- 1,7 ---- // This file written completely by Tim Johnson (Tim@TimMUD) + string *banned_muds = ({}); + static void process_startup_req(int protocol, mixed info, int fd){ // Handles startup stuff. // Loads info into newinfo mapping. *************** *** 10,16 **** // also, should verify that all the fields are the right type trr("info: "+identify(info)); ! trr("process_startup_req: protocol="+protocol+", mud="+info[2]); if(sizeof(info)<18){ // smallest protocol is protocol 1/2 which have size 18 --- 12,20 ---- // also, should verify that all the fields are the right type trr("info: "+identify(info)); ! trr("process_startup_req: protocol="+protocol+", mud="+info[2],"blue"); ! ! if(member_array(info[2], banned_muds) != -1) return; if(sizeof(info)<18){ // smallest protocol is protocol 1/2 which have size 18 *************** *** 28,48 **** })); return; } - //sscanf(socket_address(fd), "%s %s", site_ip,junk); - //socket_bind(fd,random(1000)+10000); - //site_ip = path_prefix(socket_status(fd)[4],"."); - //if(!site_ip || site_ip == "" || site_ip == "*"){ - //if(true()){ - trr("bad ip "+site_ip+" from "+info[2]); - //socket_close(fd); - //return; - //} - //junk = "foo"; trr("fd is:" +fd); site_ip=socket_address(fd); trr("site_ip: "+site_ip); newinfo = ([ "ip":site_ip, "connect_time":time(), "disconnect_time":0, --- 32,43 ---- })); return; } trr("fd is:" +fd); site_ip=socket_address(fd); trr("site_ip: "+site_ip); newinfo = ([ + "name":info[2], "ip":site_ip, "connect_time":time(), "disconnect_time":0, *************** *** 168,177 **** })); return; } ! if(mudinfo[info[2]] && mudinfo[info[2]]["password"] != newinfo["password"]){ // if MUD is already known, not connected, and wrong password if(newinfo["ip"]==mudinfo[info[2]]["ip"]){ // same IP as last time... let's just trust 'em... write_data(fd,({ "error",5,router_name,0,info[2],0, "warning", // nothing in error summary that seems applicable? --- 163,173 ---- })); return; } ! if(mudinfo[info[2]] && sizeof(mudinfo[info[2]]) && mudinfo[info[2]]["password"] != newinfo["password"]){ // if MUD is already known, not connected, and wrong password if(newinfo["ip"]==mudinfo[info[2]]["ip"]){ // same IP as last time... let's just trust 'em... + trr("Wrong password, but right IP","green"); write_data(fd,({ "error",5,router_name,0,info[2],0, "warning", // nothing in error summary that seems applicable? *************** *** 180,186 **** })); } else{ ! trr("wrong password, and from a new IP"); write_data(fd,({ "error", 5, --- 176,182 ---- })); } else{ ! trr("wrong password, and from a new IP","red"); write_data(fd,({ "error", 5, *************** *** 195,205 **** return; } } ! if(!mudinfo[info[2]]){ // if new MUD, assign it a password ! newinfo["password"]=random(10000); // Change this maybe... see if the password is supposed to be in a certain range } // MUD should be okay at this point. trr("about to update the mudinfo..."); mudinfo[info[2]]=newinfo; // update the mudinfo --- 191,204 ---- return; } } ! //trr("Right IP.","green"); ! if(!mudinfo[info[2]] || !newinfo["password"] || mudinfo[info[2]]["password"] != newinfo["password"] ){ // if new MUD, assign it a password ! newinfo["password"]=random(9999)+1; ! trr("Assigning password "+newinfo["password"],"white"); // Change this maybe... see if the password is supposed to be in a certain range } + else trr("Right password. Known: "+mudinfo[info[2]]["password"]+", current: "+newinfo["password"],"green"); // MUD should be okay at this point. trr("about to update the mudinfo..."); mudinfo[info[2]]=newinfo; // update the mudinfo *************** *** 210,215 **** mudinfo_updates[info[2]]=mudinfo_update_counter; send_mudlist_updates(info[2], newinfo["old_mudlist_id"]); broadcast_mudlist(info[2]); ! if(member_array("channel", keys(newinfo["services"]))) ! send_chanlist_reply(info[2], newinfo["old_chanlist_id"]); } --- 209,221 ---- mudinfo_updates[info[2]]=mudinfo_update_counter; send_mudlist_updates(info[2], newinfo["old_mudlist_id"]); broadcast_mudlist(info[2]); ! if(member_array("channel", keys(newinfo["services"])) != -1) ! send_chanlist_reply(info[2], ( newinfo["old_chanlist_id"]) ? newinfo["old_chanlist_id"] : (random(1138) * 1138) ); ! else { ! trr("-------------------------------","blue"); ! trr("It looks like "+info[2]+" doesn't have a channel service?!?","blue"); ! trr("These are the services reported: "+identify(newinfo["services"]),"blue"); ! trr("This is what newinfo looks like: "+identify(newinfo),"blue"); ! trr("-------------------------------","blue"); ! } } diff -c -r --new-file ds2.0r26/lib/secure/daemon/i3router/read_callback.h ds2.0r29/lib/secure/daemon/i3router/read_callback.h *** ds2.0r26/lib/secure/daemon/i3router/read_callback.h Sun Apr 9 23:51:25 2006 --- ds2.0r29/lib/secure/daemon/i3router/read_callback.h Wed Jul 5 00:01:12 2006 *************** *** 23,29 **** string mudname; int i; ! trr("Received from fd("+fd+"), fd("+socket_address(fd)+")\n"+identify(info)); // Base info in a packet is of size 6. if(sizeof(info)<6 || !stringp(info[0]) || --- 23,29 ---- string mudname; int i; ! trr("Received from fd("+fd+"), fd("+socket_address(fd)+")\n"+identify(info),((info[0] == "auth-mud-req" || info[0] == "auth-mud-reply") ? "magenta" : "green")); // Base info in a packet is of size 6. if(sizeof(info)<6 || !stringp(info[0]) || *************** *** 129,135 **** if(info[4]==router_name) { // Something meant for the router but not handled by now! send_error(info[2],info[3],"not-imp","Unknown command sent to router: "+info[0],info); ! trr("unhandled command meant for router: "+info[0]); log_file("server","UNHANDLED PACKET:\n"+identify(info)+"\n"); return; } --- 129,135 ---- if(info[4]==router_name) { // Something meant for the router but not handled by now! send_error(info[2],info[3],"not-imp","Unknown command sent to router: "+info[0],info); ! trr("unhandled packet meant for router: "+info[0],"red"); log_file("server","UNHANDLED PACKET:\n"+identify(info)+"\n"); return; } diff -c -r --new-file ds2.0r26/lib/secure/daemon/i3router/send_chanlist_reply.h ds2.0r29/lib/secure/daemon/i3router/send_chanlist_reply.h *** ds2.0r26/lib/secure/daemon/i3router/send_chanlist_reply.h Sun Apr 9 23:51:25 2006 --- ds2.0r29/lib/secure/daemon/i3router/send_chanlist_reply.h Wed Jul 5 00:01:12 2006 *************** *** 7,26 **** int i; // counter trr("send_chanlist_reply, mudname="+mudname+", old_chanid="+old_chanid); foreach(channame in keys(channel_updates)){ ! #ifndef SEND_WHOLE_CHANLIST ! if(channel_updates[channame]>old_chanid){ // needs updating ! #endif ! if(!channels[channame]){ // add to output; ! out[channame] = 0; ! } ! else{ ! out[channame] = ({ channels[channame][1], ! channels[channame][0] }); // host, type ! } ! #ifndef SEND_WHOLE_CHANLIST } ! #endif } write_data(connected_muds[mudname],({ "chanlist-reply", 5, --- 7,27 ---- int i; // counter trr("send_chanlist_reply, mudname="+mudname+", old_chanid="+old_chanid); foreach(channame in keys(channel_updates)){ ! //#ifndef SEND_WHOLE_CHANLIST ! // if(channel_updates[channame]>old_chanid){ // needs updating ! //#endif ! if(!channels[channame]){ // add to output; ! out[channame] = 0; } ! else{ ! out[channame] = ({ channels[channame][1], ! channels[channame][0] }); // host, type ! } ! //#ifndef SEND_WHOLE_CHANLIST ! // } ! //#endif } + trr("Chanlist: "+identify(out),"blue"); write_data(connected_muds[mudname],({ "chanlist-reply", 5, diff -c -r --new-file ds2.0r26/lib/secure/daemon/i3router/server.c ds2.0r29/lib/secure/daemon/i3router/server.c *** ds2.0r26/lib/secure/daemon/i3router/server.c Sun Apr 9 23:51:26 2006 --- ds2.0r29/lib/secure/daemon/i3router/server.c Wed Jul 5 00:01:12 2006 *************** *** 18,24 **** #define SEND_WHOLE_MUDLIST // SEND_WHOLE_CHANLIST makes it act like the official I3 server instead of like the I3 specs #define SEND_WHOLE_CHANLIST - inherit LIB_SAVE; inherit LIB_CLEAN; // Unsaved variables... --- 18,23 ---- *************** *** 98,105 **** #include "./core_stuff.h" #include "./funcs.h" #include "./socket_stuff.h" ! ! // trrging stuff... mapping query_mudinfo(){ return copy(mudinfo); } --- 97,103 ---- #include "./core_stuff.h" #include "./funcs.h" #include "./socket_stuff.h" ! #include "./hosted_channels.h" // trrging stuff... mapping query_mudinfo(){ return copy(mudinfo); } *************** *** 124,129 **** --- 122,142 ---- return copy(connected_muds); } + string *AddBannedMud(string str){ + if( !((int)master()->valid_apply(({ "SECURE" }))) ) + error("Illegal attempt to access admintool: "+get_stack()+" "+identify(previous_object(-1))); + + banned_muds += ({ str }); + return banned_muds; + } + + string *RemoveBannedMud(string str){ + if( !((int)master()->valid_apply(({ "SECURE" }))) ) + error("Illegal attempt to access admintool: "+get_stack()+" "+identify(previous_object(-1))); + + banned_muds -= ({ str }); + return banned_muds; + } void clear_discs(){ string mudname; diff -c -r --new-file ds2.0r26/lib/secure/daemon/imc2.c ds2.0r29/lib/secure/daemon/imc2.c *** ds2.0r26/lib/secure/daemon/imc2.c Mon May 15 11:25:20 2006 --- ds2.0r29/lib/secure/daemon/imc2.c Wed Jul 5 00:01:05 2006 *************** *** 124,130 **** #define ADMIN(x) archp(x) #endif ! #define HTML_LOCATION "http://dead-souls.sourceforge.net/" // Other things that could be #define'd... // INVIS(x) !visible(x) --- 124,130 ---- #define ADMIN(x) archp(x) #endif ! #define HTML_LOCATION "http://dead-souls.net/" // Other things that could be #define'd... // INVIS(x) !visible(x) diff -c -r --new-file ds2.0r26/lib/secure/daemon/include/imc2_code.h ds2.0r29/lib/secure/daemon/include/imc2_code.h *** ds2.0r26/lib/secure/daemon/include/imc2_code.h Wed Apr 5 19:33:19 2006 --- ds2.0r29/lib/secure/daemon/include/imc2_code.h Wed Jul 5 00:01:12 2006 *************** *** 43,49 **** #define ADMIN(x) archp(x) #endif ! #define HTML_LOCATION "http://dead-souls.sourceforge.net/" // Other things that could be #define'd... // INVIS(x) !visible(x) --- 43,49 ---- #define ADMIN(x) archp(x) #endif ! #define HTML_LOCATION "http://dead-souls.net/" // Other things that could be #define'd... // INVIS(x) !visible(x) diff -c -r --new-file ds2.0r26/lib/secure/daemon/master.c ds2.0r29/lib/secure/daemon/master.c *** ds2.0r26/lib/secure/daemon/master.c Sun Jun 18 16:21:05 2006 --- ds2.0r29/lib/secure/daemon/master.c Sun Jul 9 19:04:30 2006 *************** *** 27,32 **** --- 27,33 ---- private static string PlayerName, rlog; private static object NewPlayer; private static mapping Groups, ReadAccess, WriteAccess; + private static string *ParserDirs = ({ "secure", "verbs", "daemon", "lib", "spells" }); void create() { Unguarded = 0; *************** *** 193,199 **** object *stack; string *privs; string priv; ! int i; if( objectp(file) ) file = base_name(file); if( ok && sizeof(ok) && ok[0] == "all" ) return 1; --- 194,200 ---- object *stack; string *privs; string priv; ! int i, privcheck; if( objectp(file) ) file = base_name(file); if( ok && sizeof(ok) && ok[0] == "all" ) return 1; *************** *** 220,238 **** } else i = sizeof(stack = previous_object(-1) + ({ ob })); while(i--) { ! if(!stack[i] || stack[i] == this_object()) continue; ! if(file_name(stack[i]) == SEFUN) continue; ! if(!(priv = query_privs(stack[i]))) return 0; ! if(!ok && oper == "read") continue; privs = explode(priv, ":"); ! if(member_array(PRIV_SECURE, privs) != -1) continue; ! if(member_array(file_privs(file), privs) != -1) continue; if(!ok && oper == "write") { if(userp(stack[i]) && check_user(stack[i], fun, file, oper)) continue; else return 0; } ! if(sizeof(privs & ok)) continue; if(userp(stack[i]) && check_user(stack[i], fun, file, oper)) continue; if(userp(stack[i]) && check_domain(stack[i], fun, file,oper)) continue; return 0; --- 221,253 ---- } else i = sizeof(stack = previous_object(-1) + ({ ob })); while(i--) { ! if(!stack[i] || stack[i] == this_object()) { ! continue; ! } ! if(file_name(stack[i]) == SEFUN) { ! continue; ! } ! if(!(priv = query_privs(stack[i]))) { ! return 0; ! } ! if(!ok && oper == "read") { ! continue; ! } privs = explode(priv, ":"); ! if(member_array(PRIV_SECURE, privs) != -1) { ! continue; ! } ! if(stringp(file) && member_array(file_privs(file), privs) != -1) { ! continue; ! } if(!ok && oper == "write") { if(userp(stack[i]) && check_user(stack[i], fun, file, oper)) continue; else return 0; } ! if(sizeof(privs & ok)) { ! continue; ! } if(userp(stack[i]) && check_user(stack[i], fun, file, oper)) continue; if(userp(stack[i]) && check_domain(stack[i], fun, file,oper)) continue; return 0; *************** *** 357,368 **** } int valid_object(object ob) { ! string file; file = file_name(ob); if( !strsrch(file, DIR_TMP) ) return 0; else if( !strsrch(file, DIR_FTP) ) return 0; else if( !strsrch(file, DIR_LOGS) ) return 0; else return 1; } --- 372,392 ---- } int valid_object(object ob) { ! string file, contents; file = file_name(ob); + contents = read_file(base_name(ob)+".c"); + if(strsrch(contents,"parse_add_rule") != -1 + || strsrch(contents, "SetRules") != -1) { + string prefix; + if(!sscanf(file,"/%s/%*s",prefix)) return 0; + if(member_array(prefix, ParserDirs) == -1) return 0; + } + if( !strsrch(file, DIR_TMP) ) return 0; else if( !strsrch(file, DIR_FTP) ) return 0; else if( !strsrch(file, DIR_LOGS) ) return 0; + else if( !strsrch(file, DIR_SECURE_SAVE) ) return 0; else return 1; } diff -c -r --new-file ds2.0r26/lib/secure/daemon/options.c ds2.0r29/lib/secure/daemon/options.c *** ds2.0r26/lib/secure/daemon/options.c Mon Jan 16 23:04:14 2006 --- ds2.0r29/lib/secure/daemon/options.c Wed Jul 5 00:48:29 2006 *************** *** 20,26 **** daemon::create(); SetNoClean(1); __MyGroups = ([]); ! __Options = ([]); __Owner = 0; } --- 20,26 ---- daemon::create(); SetNoClean(1); __MyGroups = ([]); ! __Options = (["notify" : 1]); __Owner = 0; } *************** *** 45,58 **** file = DIR_POSTAL+"/"+who[0..0]+"/"+who; if(unguarded((: file_size, file :)) != -2) unguarded((: mkdir, file :)); __MyGroups = ([]); ! __Options = ([]); __Owner = who; unguarded((: save_object, file+"/postalrc" :)); } static private void load_options(string who) { string file; - if(who == __Owner) return; this_object()->assure_box_exists(who); if(__Owner == who) { --- 45,57 ---- file = DIR_POSTAL+"/"+who[0..0]+"/"+who; if(unguarded((: file_size, file :)) != -2) unguarded((: mkdir, file :)); __MyGroups = ([]); ! __Options = (["notify":1]); __Owner = who; unguarded((: save_object, file+"/postalrc" :)); } static private void load_options(string who) { string file; if(who == __Owner) return; this_object()->assure_box_exists(who); if(__Owner == who) { *************** *** 65,71 **** static private void save_options() { string file; - file = DIR_POSTAL+"/"+__Owner[0..0]+"/"+__Owner+"/postalrc"; unguarded((: save_object, file :)); } --- 64,69 ---- diff -c -r --new-file ds2.0r26/lib/secure/daemon/snoop.c ds2.0r29/lib/secure/daemon/snoop.c *** ds2.0r26/lib/secure/daemon/snoop.c Sun Jun 18 16:21:06 2006 --- ds2.0r29/lib/secure/daemon/snoop.c Wed Jul 5 19:58:20 2006 *************** *** 59,70 **** string *immune; string name; if(!str) str = "foo"; str = lower_case(str); foo = find_player(str); if(sizeof(snoopers)){ foreach(object snoopbox in snoopers){ ! if(snoopbox && grepp("#",file_name(snoopbox)) ) { } else snoopers -= ({snoopbox}); if(snoopbox && snoopbox->GetSnooped() && snoopbox->GetSnooped() == str) { --- 59,74 ---- string *immune; string name; + //tc("hello."); if(!str) str = "foo"; str = lower_case(str); foo = find_player(str); if(sizeof(snoopers)){ foreach(object snoopbox in snoopers){ ! //tc("snooper: "+identify(snoopbox)); ! //if(snoopbox && grepp("#",file_name(snoopbox)) ) { ! if(clonep(snoopbox) ) { ! //tc("snooped: "+ file_name(snoopbox)+": "+snoopbox->GetSnooped()+"\n","yellow"); } else snoopers -= ({snoopbox}); if(snoopbox && snoopbox->GetSnooped() && snoopbox->GetSnooped() == str) { *************** *** 88,100 **** void CheckSnooped(){ object *lusers = users(); ! if(!compare_array(lusers, prevusers) || just_loaded){ ! just_loaded = 0; ! foreach(object user in lusers){ ! CheckBot(user->GetKeyName()); ! } } ! else CheckBot("tanstaafl"); prevusers = lusers; } --- 92,104 ---- void CheckSnooped(){ object *lusers = users(); ! //if(!compare_array(lusers, prevusers) || just_loaded){ ! just_loaded = 0; ! foreach(object user in lusers){ ! CheckBot(user->GetKeyName()); } ! //} ! //else CheckBot("tanstaafl"); prevusers = lusers; } *************** *** 120,125 **** --- 124,136 ---- return 1; } + int eventDestruct(){ + if( !((int)master()->valid_apply(({ "SECURE" }))) ) + error("Illegal attempt to destruct snoop: "+get_stack()+" "+identify(previous_object(-1))); + return ::eventDestruct(); + } + + void heart_beat(){ count++; *************** *** 245,258 **** } int Report(){ ! if( !((int)master()->valid_apply(({ "PRIV_SECURE" }))) ){ return 0; } ! tc("Watchers: "+identify(Watchers)); ! tc("snoopers: "+identify(snoopers)); ! tc("prevusers: "+identify(prevusers)); ! tc("snooped: "+identify(snooped)); ! tc("monitored: "+identify(monitored)); return 1; } --- 256,269 ---- } int Report(){ ! if( !((int)master()->valid_apply(({ PRIV_SECURE }))) ){ return 0; } ! write("Watchers: "+identify(Watchers)+"\n"); ! write("snoopers: "+identify(snoopers)+"\n"); ! //write("prevusers: "+identify(prevusers)+"\n"); ! write("snooped: "+identify(snooped)+"\n"); ! write("monitored: "+identify(monitored)+"\n"); return 1; } diff -c -r --new-file ds2.0r26/lib/secure/include/bboard.h ds2.0r29/lib/secure/include/bboard.h *** ds2.0r26/lib/secure/include/bboard.h Wed Sep 28 19:34:12 2005 --- ds2.0r29/lib/secure/include/bboard.h Wed Jul 5 00:48:29 2006 *************** *** 1,5 **** ! #define BBOARD_DIR "/adm/save/boards/" ! #define BBOARD_EDIT "/tmp/bb/" #define BBOARD_OK 0 #define BAD_DATA 1 --- 1,5 ---- ! #define BBOARD_DIR "/save/boards/" ! #define BBOARD_EDIT "/tmp/" #define BBOARD_OK 0 #define BAD_DATA 1 diff -c -r --new-file ds2.0r26/lib/secure/include/compat.h ds2.0r29/lib/secure/include/compat.h *** ds2.0r26/lib/secure/include/compat.h Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/secure/include/compat.h Wed Jul 5 00:01:05 2006 *************** *** 0 **** --- 1,62 ---- + #ifndef s_lpu_h + #define s_lpu_h + + #define ROOM "/lib/std/room" + #define OBJECT "/lib/std/item" + #define OB_SIMUL_EFUN "/secure/sefun/sefun" + #define __DIR__ "/domains/lpuni/" + + #define set_light SetAmbientLight + #define set_short SetShort + #define set_long SetLong + #define set_items SetItems + #define set_exits SetExits + #define query_exit GetExit + #define set_property SetProperty + #define set_name SetKeyName + #define set_id SetId + #define set_no_clean SetNoClean + #define set_smell_string SetSmell + #define set_smell SetSmell + #define set_properties SetProperties + #define set_door SetDoor + #define set_race SetRace + #define set_gender SetGender + #define set_level SetLevel + #define set_body_type SetProperty + #define set_hp SetHealthPoints + #define set_class SetClass + #define set_spell_chance SetSpellChance + #define set_spell SetSpell + #define set_skills SetSkills + #define set_skill SetSkill + #define set_spell_chance SetSpellChance + #define set_emotes SetActions + #define set_wielding_limbs SetWieldingLimbs + #define set_wc SetClass + #define set_type SetWeaponType + #define set_mass SetMass + #define set_value SetValue + #define set_listen_string SetListen + #define set_listen SetListen + #define set_edit_ok valid_edit + #define POLITICS_D "/secure/daemon/politics" + #define set_search SetSearch + #define set_paralyzed SetParalyzed + #define set_pre_exit_functions SetProperty + #define MONSTER LIB_SENTIENT + #define monster sentient + #define set_money SetCurrency + #define add_exit AddExit + #define set_read SetRead + #define set_prevent_get SetPreventGet + #define VAULT LIB_ROOM + #define set_day_long SetDayLong + #define set_night_long SetNightLong + #define set_open SetOpen + #define query_open GetOpen + #define remove_item_description RemoveItem + #define remove_exit RemoveExit + #define add_item_description AddItem + + #endif /* s_lpu_h */ diff -c -r --new-file ds2.0r26/lib/secure/include/daemons.h ds2.0r29/lib/secure/include/daemons.h *** ds2.0r26/lib/secure/include/daemons.h Sun Jun 18 16:21:06 2006 --- ds2.0r29/lib/secure/include/daemons.h Wed Jul 5 00:01:05 2006 *************** *** 47,55 **** #define STARGATE_D DIR_DAEMONS "/stargate" #define TERMINAL_D DIR_DAEMONS "/terminal" #define TIME_D DIR_DAEMONS "/time" - #ifdef Dead SoulsLPMud #define UNDERWORLD_D DIR_DAEMONS "/underworld" - #endif #define UNIQUE_D DIR_DAEMONS "/unique" #define USERS_D DIR_SECURE_DAEMONS "/users" #define VERBS_D DIR_DAEMONS "/verbs" --- 47,53 ---- diff -c -r --new-file ds2.0r26/lib/secure/include/dirs.h ds2.0r29/lib/secure/include/dirs.h *** ds2.0r26/lib/secure/include/dirs.h Wed Apr 12 23:51:12 2006 --- ds2.0r29/lib/secure/include/dirs.h Sun Jul 9 19:04:30 2006 *************** *** 16,21 **** --- 16,22 ---- #define DIR_SUICIDE DIR_DATA "/suicide" #define DIR_RID DIR_DATA "/rid" #define DIR_SECURE_DAEMONS_SAVE DIR_DATA "/daemons" + #define DIR_SECURE_VERBS DIR_SECURE "/verbs" #define DIR_VOTES DIR_DATA "/votes" #define DIR_GOSSIP DIR_DATA "/gossip" diff -c -r --new-file ds2.0r26/lib/secure/include/global.h ds2.0r29/lib/secure/include/global.h *** ds2.0r26/lib/secure/include/global.h Wed Apr 5 19:33:19 2006 --- ds2.0r29/lib/secure/include/global.h Wed Jul 5 00:01:05 2006 *************** *** 1,9 **** #ifndef __GLOBAL_H #define __GLOBAL_H ! #define __nightmare__ 4.5 ! #define __nightmare5__ ! #define Dead SoulsLPMud #define DAY_ONE 720550800 --- 1,11 ---- #ifndef __GLOBAL_H #define __GLOBAL_H ! #include ! ! #if COMPAT_MODE ! #include ! #endif #define DAY_ONE 720550800 diff -c -r --new-file ds2.0r26/lib/secure/include/lib.h ds2.0r29/lib/secure/include/lib.h *** ds2.0r26/lib/secure/include/lib.h Sun Jun 18 16:21:07 2006 --- ds2.0r29/lib/secure/include/lib.h Wed Jul 5 00:48:30 2006 *************** *** 86,91 **** --- 86,92 ---- #define LIB_RIFLE DIR_LIB "/rifle" #define LIB_ROUND DIR_LIB "/round" #define LIB_SCROLL DIR_LIB "/scroll" + #define LIB_SECURE_BOARD DIR_SECURE_LIB "/bboard" #define LIB_SENTIENT DIR_LIB "/sentient" #define LIB_SERVER DIR_SECURE_LIB "/net/server" #define LIB_SHADOW DIR_LIB "/shadow" diff -c -r --new-file ds2.0r26/lib/secure/include/network.h ds2.0r29/lib/secure/include/network.h *** ds2.0r26/lib/secure/include/network.h Wed Apr 5 19:33:20 2006 --- ds2.0r29/lib/secure/include/network.h Wed Jul 5 00:01:05 2006 *************** *** 2,8 **** #define __NETWORK_H #include ! #include #define MUD 0 #define STREAM 1 --- 2,8 ---- #define __NETWORK_H #include ! //#include #define MUD 0 #define STREAM 1 diff -c -r --new-file ds2.0r26/lib/secure/include/save.h ds2.0r29/lib/secure/include/save.h *** ds2.0r26/lib/secure/include/save.h Sat Apr 22 15:20:53 2006 --- ds2.0r29/lib/secure/include/save.h Wed Jul 5 00:01:05 2006 *************** *** 20,25 **** --- 20,26 ---- #define SAVE_PLAYER_LIST DIR_SAVE "/player_list" #define SAVE_POLITICS DIR_SECURE_SAVE "/politics" #define SAVE_RACES DIR_SAVE "/races" + #define SAVE_ROUTER DIR_SECURE_SAVE "/router" #define SAVE_SERVICES DIR_SAVE "/services" #define SAVE_SNOOP DIR_SECURE_SAVE "/snoop" #define SAVE_SOUL DIR_SAVE "/soul" diff -c -r --new-file ds2.0r26/lib/secure/lib/bboard.c ds2.0r29/lib/secure/lib/bboard.c *** ds2.0r26/lib/secure/lib/bboard.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/secure/lib/bboard.c Wed Jul 5 00:48:30 2006 *************** *** 0 **** --- 1,274 ---- + /* /lib/bboard.c + * /lib/bboard.c + * from Nightmare 3.3 + * the Dead Souls bulletin board system + * created by Descartes of Borg 940920 + */ + + + #include + #include + #include "include/bboard.h" + + inherit LIB_ITEM; + + static private string __BoardID; + static private string *__EditOK; + static string globalstr, globalfile; + + void create() { + item::create(); + SetNoClean(1); + SetPreventGet("You cannot get that!"); + SetPreventPut("You cannot put that in there!"); + SetPreventDrop("Drop a bulletin board?"); + __EditOK = ({}); + } + + void init() { + item::init(); + add_action("cmd_post", "post"); + add_action("cmd_read", "read"); + add_action("cmd_followup_and_respond", ({ "followup", "respond "})); + add_action("cmd_remove", "remove"); + add_action("cmd_edit", "edit"); + if(!creatorp(this_player())) return; + } + + static private int valid_edit(string author) { + string who; + + who = (string)this_player()->GetKeyName(); + if(who == author) return 1; + if(archp(this_player())) return 1; + if(member_array(who, __EditOK) != -1) return 1; + return (int)master()->valid_apply(({})); + } + + int cmd_post(string str) { + string file; + + if(!str) return notify_fail("You must specify a subject.\n"); + if(file_exists(file = DIR_TMP+"/"+(string)this_player()->GetKeyName())) { + message("system", "You have an abandoned post waiting.",this_player()); + message("system", " e)dit it, or start n)ew", this_player()); + message("prompt", "\nCommand (default 'n'): ", this_player()); + input_to("begin_post", str, file, (: continue_post :)); + } + else begin_post("n", str, file, (: continue_post :)); + return 1; + } + + static void begin_post(string cmd, string subj, string file, function f) { + if(cmd == "" || !cmd) cmd = "n"; + else cmd = cmd[0..0]; + if(cmd != "n" && cmd != "e") { + message("system", "Invalid bulletin board command.", this_player()); + return; + } + if(cmd == "n" && file_exists(file)) rm(file); + (*f)(subj, file); + } + + void continue_post(string subj, string file) { + this_player()->eventEdit(file, (: end_post, subj, 0 :)); + } + + void end_post(string subj, string mail) { + string file, msg; + + file = DIR_TMP "/" + (string)this_player()->GetKeyName(); + if(!(msg = read_file(file))) { + message("system", "No file read!", this_player()); + if(file_exists(file)) rm(file); + return; + } + else rm(file); + if( !mail ) + BBOARD_D->add_post(query_board_id(), + (string)this_player()->GetCapName(), subj, msg); + message("system", "Message posted!", this_player()); + } + + int cmd_read(string str) { + string junk; + mapping *posts; + int x, i, maxi; + + if(str){ + if(str == "board" || sscanf(str,"board %s",junk) ) { + write("To read the first post, type: read 1"); + write("To read the second one: read 2"); + write("And so on."); + return 1; + } + + maxi = sizeof(posts = (mapping *)BBOARD_D->query_posts(query_board_id())); + if(!str) { + for(i=0, x = -1; iGetKeyName(), + posts[i]["read"]) == -1) { + x = i; + break; + } + if(x == -1) return notify_fail("No unread posts.\n"); + } + else if(!(x = to_int(str))) return notify_fail("Read what?\n"); + else x--; + if(x < 0 || x >= sizeof(posts)) + return notify_fail("Invalid post number.\n"); + str = "Post #%^YELLOW%^" + (x+1) + "%^RESET%^ by %^YELLOW%^" + + posts[x]["author"] + "%^RESET%^\nSubject: %^CYAN%^" + + posts[x]["subject"] + "%^RESET%^\n\n"; + str += posts[x]["post"]; + + BBOARD_D->mark_read(query_board_id(),x,(string)this_player()->GetKeyName()); + this_player()->eventPage(explode(str, "\n"), "system"); + return 1; + } + } + + int cmd_followup_and_respond(string str) { + mapping post; + function f; + string file, verb; + int x; + + if(!str) return notify_fail(capitalize(verb=query_verb())+" which + post?\n"); + if((x=to_int(str)) < 1 || + x>(int)BBOARD_D->query_number_posts(query_board_id())) + + return notify_fail("Invalid post number.\n"); + x--; + post = (mapping)BBOARD_D->query_post(query_board_id(), x); + if((verb = query_verb()) == "respond") f = (: continue_mail, post :); + else f = (: continue_followup, post :); + str = post["subject"]; + if(!str) str = "Re: "+possessive_noun(post["author"])+" post"; + else if(strlen(str) <= 4 || str[0..3] != "Re: ") str = "Re: "+str; + if(file_exists(file = DIR_TMP+"/"+(string)this_player()->GetKeyName())) { + message("system", "You have an abandoned post waiting.",this_player()); + message("system", " e)dit it, or start n)ew", this_player()); + message("prompt", "\nCommand (default 'n'): ", this_player()); + input_to("begin_post", str, file, f); + } + else begin_post("n", str, file, f); + return 1; + } + + void continue_followup(mapping post, string subj, string file) { + message("prompt", "\nInclude original text (default 'n'): ",this_player()); + input_to("check_include_text", subj, file, post, 0); + } + + void continue_mail(mapping post, string subj, string file) { + message("prompt", "\nInclude original text (default 'n'): ",this_player()); + input_to("check_include_text", subj, file, post, 1); + } + + static void check_include_text(string ans, string subj, string file, mapping + post, int mail) { + + string msg; + + if(ans == "" || !ans) ans = "n"; + else ans = ans[0..0]; + if(ans == "y") { + msg = post["author"] + " once wrote...\n>"; + msg += implode(explode(post["post"], "\n"), "\n> ")+"\n"; + globalstr = msg; + globalfile = file; + unguarded( (: write_file(globalfile, globalstr) :) ); + } + this_player()->eventEdit(file, (: end_post, subj, (mail ? post : 0) :)); + } + + int cmd_remove(string str) { + mapping post; + int x; + + if((x = to_int(str)) < 1 || + x > (int)BBOARD_D->query_number_posts(query_board_id())) + return notify_fail("Invalid post number.\n"); + post = (mapping)BBOARD_D->query_post(query_board_id(), x-1); + if(!valid_edit(convert_name(post["author"]))) + return notify_fail("You do not have permission to remove that!\n"); + BBOARD_D->remove_post(query_board_id(), x-1); + message("system", "Post "+x+" removed.", this_player()); + return 1; + } + + int cmd_edit(string str) { + mapping post; + string file; + int x; + + if((x = to_int(str)) < 1 || + x > (int)BBOARD_D->query_number_posts(query_board_id())) + return notify_fail("Invalid post number.\n"); + post = (mapping)BBOARD_D->query_post(query_board_id(), x-1); + if(!valid_edit(convert_name(post["author"]))) + return notify_fail("You do not have permission to edit that post!\n"); + file = DIR_TMP+"/"+(string)this_player()->GetKeyName()+".bb"; + if(file_exists(file)) rm(file); + globalstr = post["post"]; + globalfile = file; + unguarded( (: write_file(globalfile, globalstr) :) ); + this_player()->edit(file, (: end_edit, post["subject"], x-1 :) ); + return 1; + } + + void end_edit(string subj, int num) { + string file, msg; + + file = DIR_TMP "/" + (string)this_player()->GetKeyName(); + if(!(msg = read_file(file))) { + message("system", "No file read!", this_player()); + return; + } + else rm(file); + BBOARD_D->remove_post(query_board_id(), num); + BBOARD_D->add_post(query_board_id(), + (string)this_player()->GetCapName(), subj, msg); + message("system", "Message posted!", this_player()); + } + + string GetExternalDesc() { + mapping *posts; + string msg; + int i, maxi; + + msg = item::GetExternalDesc(); + maxi = sizeof(posts = (mapping *)BBOARD_D->query_posts(query_board_id())); + msg += "\n"; + if(!maxi) msg += "There are currently no posts.\n"; + else for(i=0; i < maxi; i++) { + int lu; + + if(!this_player()) lu = 1; + else if(member_array((string)this_player()->GetKeyName(), + posts[i]["read"]) == -1) lu = 0; + else lu = 1; + msg += sprintf("[%:-3d] %s %:-17s \"%:-27s %s\n", + (i+1), (lu ? " " : "(new)"), posts[i]["author"]+":", + posts[i]["subject"]+"\"", query_board_time(posts[i]["time"])); + } + return msg; + } + + void set_board_id(string str) { __BoardID = str; } + + string query_board_id() { return __BoardID; } + + string query_board_time(int x) { + string date, day, mon, year, hour, ret; + + if(sscanf(ctime(x), "%s %s %s %s %s", day, mon, date, hour, year) !=5) + sscanf(ctime(x), "%s %s %s %s %s", day, mon, date, hour, year); + + sscanf(hour, "%s:%s:%*s", hour, ret); + return(hour+ret+" "+day+" "+date+" "+mon); + } + + diff -c -r --new-file ds2.0r26/lib/secure/lib/include/bboard.h ds2.0r29/lib/secure/lib/include/bboard.h *** ds2.0r26/lib/secure/lib/include/bboard.h Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/secure/lib/include/bboard.h Wed Jul 5 00:48:30 2006 *************** *** 0 **** --- 1,25 ---- + #ifndef __BBOARD_H + #define __BBOARD_H + + void create(); + void init(); + static private int valid_edit(string author); + int cmd_post(string str); + static void begin_post(string cmd, string subj, string file, function f); + void continue_post(string subj, string file); + void abort_edit(); + void end_post(string subj, string mail); + int cmd_read(string str); + int cmd_followup_and_respond(string str); + void continue_followup(mapping post, string subj, string file); + void continue_mail(mapping post, string subj, string file); + static void check_include_text(string ans, string subj, string file, mapping post, int mail); + int cmd_eventDestruct(string str); + int cmd_edit(string str); + void end_edit(string subj, int num); + varargs string GetLong(string str); + void set_board_id(string str); + string query_board_id(); + string query_board_time(int x); + + #endif /* __BBOARD_H */ diff -c -r --new-file ds2.0r26/lib/secure/modules/money.c ds2.0r29/lib/secure/modules/money.c *** ds2.0r26/lib/secure/modules/money.c Mon Jan 16 23:00:14 2006 --- ds2.0r29/lib/secure/modules/money.c Wed Jul 5 00:01:06 2006 *************** *** 24,29 **** --- 24,30 ---- globalstr2 = ""; globalstr3 = ""; + if(inherits(LIB_NPC,ob)) npc = 1; if(!intp(val) ) sscanf(val,"%s %d",junk1,amount); *************** *** 66,78 **** this_object()->eventGeneralStuff(globalstr); unguarded( (: cp(globalstr,globalstr3) :) ); unguarded( (: rm(globalstr) :) ); return 1; } int eventModCost(object ob, string type, mixed val){ string new_line, junk; int amount; ! sscanf(val,"%s %d",junk,amount); globalstr = base_name(ob)+".c"; if(!check_privs(this_player(),globalstr)){ write("You do not appear to have access to this file. Modification aborted."); --- 67,82 ---- this_object()->eventGeneralStuff(globalstr); unguarded( (: cp(globalstr,globalstr3) :) ); unguarded( (: rm(globalstr) :) ); + reload(ob); return 1; } int eventModCost(object ob, string type, mixed val){ string new_line, junk; int amount; ! ! if(stringp(val)) sscanf(val,"%s %d",junk,amount); ! else amount = val; globalstr = base_name(ob)+".c"; if(!check_privs(this_player(),globalstr)){ write("You do not appear to have access to this file. Modification aborted."); *************** *** 94,99 **** --- 98,105 ---- unguarded( (: write_file(globalstr, globalstr2, 1) :) ); this_object()->eventGeneralStuff(globalstr); + reload(ob); + return 1; } diff -c -r --new-file ds2.0r26/lib/secure/modules/room.c ds2.0r29/lib/secure/modules/room.c *** ds2.0r26/lib/secure/modules/room.c Fri Mar 24 14:41:23 2006 --- ds2.0r29/lib/secure/modules/room.c Wed Jul 5 00:01:06 2006 *************** *** 15,21 **** mixed make(string str) { int enter; - string *dir_array; string *exits; string *enters; string foo, current_dir, current_room, this_room, new_room, room_dir; --- 15,20 ---- *************** *** 37,45 **** room = environment(this_player()); current_dir = this_player()->query_cwd(); current_room = base_name(room); ! dir_array = explode(current_room, "/"); ! dir_array -= ({ dir_array[sizeof(dir_array) - 1] }); ! room_dir = "/"+implode(dir_array,"/"); if(file_exists(current_room+".c") && !check_privs(this_player(),current_room+".c")){ --- 36,42 ---- room = environment(this_player()); current_dir = this_player()->query_cwd(); current_room = base_name(room); ! room_dir = path_prefix(current_room); if(file_exists(current_room+".c") && !check_privs(this_player(),current_room+".c")){ *************** *** 83,89 **** } if(strsrch(arg2,".c") == -1) arg2 += ".c"; ! if(strsrch(arg2," ") != -1) arg2 = replace_string(arg2," ",""); if(file_exists(arg2)) new_file = arg2; else if(strsrch(arg2,"./") != -1) { --- 80,86 ---- } if(strsrch(arg2,".c") == -1) arg2 += ".c"; ! if(strsrch(arg2," ") != -1) arg2 = replace_string(arg2," ","_"); if(file_exists(arg2)) new_file = arg2; else if(strsrch(arg2,"./") != -1) { *************** *** 111,117 **** return 1; } ! if(new_file[0..7] == "/realms/" && strsrch(new_file,"/area/") != -1){ if(!file_exists(new_file)) cp("/obj/area_room.c",new_file); } else { --- 108,114 ---- return 1; } ! if(new_file[0..7] == "/realms/" && strsrch(new_file,"/area/room/") != -1){ if(!file_exists(new_file)) cp("/obj/area_room.c",new_file); } else { *************** *** 386,394 **** if(remote && member_array("out",load_object(room)->GetExits()) != -1) return 0; ! globaltmp = remove_matching_line(globaltmp,"SetObviousExits",1); ! globaltmp = remove_matching_line(globaltmp,"SetExits",1); ! globaltmp = remove_matching_line(globaltmp,"SetDoor",1); globaltmp = remove_matching_line(globaltmp,"SetEnters",1); globaltmp = remove_matching_line(globaltmp,"//extras",1); //tc("remote: "+remote,"yellow"); --- 383,391 ---- if(remote && member_array("out",load_object(room)->GetExits()) != -1) return 0; ! //globaltmp = remove_matching_line(globaltmp,"SetObviousExits",1); ! //globaltmp = remove_matching_line(globaltmp,"SetExits",1); ! //globaltmp = remove_matching_line(globaltmp,"SetDoor",1); globaltmp = remove_matching_line(globaltmp,"SetEnters",1); globaltmp = remove_matching_line(globaltmp,"//extras",1); //tc("remote: "+remote,"yellow"); diff -c -r --new-file ds2.0r26/lib/secure/obj/arch_board.c ds2.0r29/lib/secure/obj/arch_board.c *** ds2.0r26/lib/secure/obj/arch_board.c Sun Jun 18 16:21:07 2006 --- ds2.0r29/lib/secure/obj/arch_board.c Wed Jul 5 00:48:30 2006 *************** *** 1,12 **** #include ! inherit LIB_BOARD; void create(){ ::create(); SetKeyName("chalkboard"); ! SetId( ({ "board", "chalkboard" })); set_board_id("admin_board"); SetShort("The Arch Board"); SetLong("This is the Arch board. You know how to use it."); --- 1,13 ---- #include + #include ! inherit LIB_SECURE_BOARD; void create(){ ::create(); SetKeyName("chalkboard"); ! SetId(({ "board", "chalkboard" })); set_board_id("admin_board"); SetShort("The Arch Board"); SetLong("This is the Arch board. You know how to use it."); *************** *** 17,23 **** } void validate(){ ! if( !((int)master()->valid_apply(({ "PRIV_ASSIST", "PRIV_SECURE" }))) ) error("Illegal attempt to access arch board: "+get_stack()+" "+identify(previous_object(-1))); } --- 18,24 ---- } void validate(){ ! if( !this_player() || !archp(this_player()) ) error("Illegal attempt to access arch board: "+get_stack()+" "+identify(previous_object(-1))); } diff -c -r --new-file ds2.0r26/lib/secure/obj/control.c ds2.0r29/lib/secure/obj/control.c *** ds2.0r26/lib/secure/obj/control.c Sun Jun 18 16:21:08 2006 --- ds2.0r29/lib/secure/obj/control.c Wed Jul 5 00:01:06 2006 *************** *** 104,109 **** --- 104,114 ---- return 1; } + if(!str || str == ""){ + write("Nothing happens."); + return 1; + } + if(environment() != owner){ write("You don't seem to be in possession of the remote control."); tell_object(environment(),"Possible security violation on remote control."); diff -c -r --new-file ds2.0r26/lib/secure/obj/glasses.c ds2.0r29/lib/secure/obj/glasses.c *** ds2.0r26/lib/secure/obj/glasses.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/secure/obj/glasses.c Wed Jul 5 00:01:06 2006 *************** *** 0 **** --- 1,34 ---- + #include + #include + #include + #include + + inherit LIB_ARMOR; + inherit MODULES_ARMOR; + inherit MODULES_CREATE; + inherit MODULES_MAPPING; + inherit MODULES_GENERIC; + inherit MODULES_ROOM; + inherit MODULES_FILE; + inherit MODULES_MONEY; + inherit MODULES_READ; + inherit MODULES_DOOR; + + static void create(){ + armor::create(); + SetKeyName("glasses"); + SetId(({"tanstaafl"})); + SetAdjectives(({"wire-rimmed", "wire rimmed"})); + SetShort("wire-rimmed glasses"); + SetLong("A pair of glasses with magic properties for Creators."); + SetMass(5); + SetBaseCost("silver",30); + SetDamagePoints(1); + SetProtection(BLUNT,1); + SetProtection(BLADE,1); + SetProtection(KNIFE,1); + SetArmorType(A_VISOR); + } + void init(){ + ::init(); + } diff -c -r --new-file ds2.0r26/lib/secure/obj/medtric.c ds2.0r29/lib/secure/obj/medtric.c *** ds2.0r26/lib/secure/obj/medtric.c Wed Apr 5 19:33:20 2006 --- ds2.0r29/lib/secure/obj/medtric.c Wed Jul 5 00:01:06 2006 *************** *** 1111,1116 **** --- 1111,1117 ---- if(!str || str=="" || str=="here") { ob = environment(this_player()); name = ob->GetShort(); + str = base_name(ob); } if(str == "me") str = this_player()->GetKeyName(); if(present(str,this_player())) { diff -c -r --new-file ds2.0r26/lib/secure/obj/mojo.c ds2.0r29/lib/secure/obj/mojo.c *** ds2.0r26/lib/secure/obj/mojo.c Sun Jun 18 16:21:08 2006 --- ds2.0r29/lib/secure/obj/mojo.c Wed Jul 5 00:01:06 2006 *************** *** 58,64 **** void heart_beat(){ if(environment() && !living(environment())) this_object()->eventDestruct(); ! if(counter == 50){ if(environment()) tell_object(environment(),"You feel the effects of the healing salve wear off."); this_object()->eventMove("/domains/town/room/furnace"); } --- 58,64 ---- void heart_beat(){ if(environment() && !living(environment())) this_object()->eventDestruct(); ! if(counter == 100){ if(environment()) tell_object(environment(),"You feel the effects of the healing salve wear off."); this_object()->eventMove("/domains/town/room/furnace"); } diff -c -r --new-file ds2.0r26/lib/secure/obj/replacer.c ds2.0r29/lib/secure/obj/replacer.c *** ds2.0r26/lib/secure/obj/replacer.c Sun Jun 18 16:21:08 2006 --- ds2.0r29/lib/secure/obj/replacer.c Wed Jul 5 00:01:06 2006 *************** *** 10,16 **** int n, active; static private void validate() { ! if( !((int)master()->valid_apply(({ "PRIV_ASSIST", "PRIV_SECURE" }))) ) error("Illegal attempt to use replacer: "+get_stack()+" "+identify(previous_object(-1))); } --- 10,17 ---- int n, active; static private void validate() { ! if(!this_player()) return 0; ! if( !((int)master()->valid_apply(({ "SECURE" }))) || !securep(this_player())) error("Illegal attempt to use replacer: "+get_stack()+" "+identify(previous_object(-1))); } *************** *** 34,39 **** --- 35,41 ---- SetVendorType(VT_TREASURE); active = 0; } + void init(){ add_action("rep_string","replace"); add_action("autorep","autorep"); diff -c -r --new-file ds2.0r26/lib/secure/obj/snooper.c ds2.0r29/lib/secure/obj/snooper.c *** ds2.0r26/lib/secure/obj/snooper.c Sun Jun 18 16:21:08 2006 --- ds2.0r29/lib/secure/obj/snooper.c Wed Jul 5 00:01:06 2006 *************** *** 85,91 **** string GetSnooped(){ //debug("I am snooping ",guy,"green"); ! if((previous_object() && base_name(previous_object())) != SNOOP_D && ! !archp(this_player())) return ""; else return guy; } --- 85,91 ---- string GetSnooped(){ //debug("I am snooping ",guy,"green"); ! if( !((int)master()->valid_apply(({ "PRIV_ASSIST", "PRIV_SECURE", "SNOOP_D" }))) ) return ""; else return guy; + //return guy; } diff -c -r --new-file ds2.0r26/lib/secure/room/arch.c ds2.0r29/lib/secure/room/arch.c *** ds2.0r26/lib/secure/room/arch.c Sun Jun 18 16:21:08 2006 --- ds2.0r29/lib/secure/room/arch.c Wed Jul 5 00:48:30 2006 *************** *** 160,166 **** ]) ); } int CanReceive(object ob) { ! if( !archp(ob) ){ message("info","The arch room is available only to "+ "admins, sorry.",ob); return 0; --- 160,166 ---- ]) ); } int CanReceive(object ob) { ! if( !archp(ob) && base_name(ob) != "/secure/obj/arch_board"){ message("info","The arch room is available only to "+ "admins, sorry.",ob); return 0; diff -c -r --new-file ds2.0r26/lib/secure/save/boards/immortal_board.o ds2.0r29/lib/secure/save/boards/immortal_board.o *** ds2.0r26/lib/secure/save/boards/immortal_board.o Sun Dec 11 21:37:14 2005 --- ds2.0r29/lib/secure/save/boards/immortal_board.o Wed Jul 5 00:01:12 2006 *************** *** 1,3 **** #/secure/daemon/bboard.c __Owner "GENERAL" ! __Posts ({(["author":"Cratylus","post":"A couple of hints: - Look in your workroom's chest for useful wiz toys. - Read /doc/README for instructions on enabling intermud channels. - There's a creator's manual in your workroom's chest. It is your friend. - Information and documentation is available at: http://dead-souls.sourceforge.net/ - Almost everything you need is in /doc. Whatever isn't there, you wouldn't understand anyway. - Make an effort to find an answer of your own before asking for help. - If you ask for help, be polite. - Have fun. ","subject":"Welcome to Dead Souls","time":1132694785,"read":({"cratylus","jayren",}),]),(["author":"Cratylus","post":"- When your stuff won't update, the elog command will help you track down the problem. - When players generate runtime errors, detailed error messages get logged to /log/player_errors . ","subject":"player errors","time":1132694930,"read":({"cratylus","jayren",}),]),(["post":"Dead Souls now sports a groovy new creation system. We're still working out the kinks and still adding features, but it's stable enough to try out. The main commands for this new system are: create, modify, add, delete, and copy. For detailed info, type: help creation ","subject":"NEW creation system","author":"Cratylus","time":1134153426,"read":({"cratylus",}),]),}) --- 1,3 ---- #/secure/daemon/bboard.c __Owner "GENERAL" ! __Posts ({(["author":"Cratylus","post":"A couple of hints: - Look in your workroom's chest for useful wiz toys. - Read /doc/README for instructions on enabling intermud channels. - There's a creator's manual in your workroom's chest. It is your friend. - Information and documentation is available at: http://dead-souls.net/ - Almost everything you need is in /doc. Whatever isn't there, you wouldn't understand anyway. - Make an effort to find an answer of your own before asking for help. - If you ask for help, be polite. - Have fun. ","subject":"Welcome to Dead Souls","time":1132694785,"read":({"cratylus","jayren",}),]),(["author":"Cratylus","post":"- When your stuff won't update, the elog command will help you track down the problem. - When players generate runtime errors, detailed error messages get logged to /log/player_errors . ","subject":"player errors","time":1132694930,"read":({"cratylus","jayren",}),]),(["post":"Dead Souls now sports a groovy new creation system. We're still working out the kinks and still adding features, but it's stable enough to try out. The main commands for this new system are: create, modify, add, delete, and copy. For detailed info, type: help creation ","subject":"NEW creation system","author":"Cratylus","time":1134153426,"read":({"cratylus",}),]),}) diff -c -r --new-file ds2.0r26/lib/secure/sefun/messaging.c ds2.0r29/lib/secure/sefun/messaging.c *** ds2.0r26/lib/secure/sefun/messaging.c Sat Mar 11 11:20:56 2006 --- ds2.0r29/lib/secure/sefun/messaging.c Wed Jul 5 00:01:06 2006 *************** *** 343,349 **** } switch(words[i]) { case "$agent_verb": ! words[i] = pluralize(verb[verb_count++]); break; case "$agent_name": --- 343,352 ---- } switch(words[i]) { case "$agent_verb": ! //words[i] = pluralize(replace_string(identify(verb),"\"","")); ! //tc("verb: "+identify(verb)); ! //tc("verb: "+typeof(verb)); ! words[i] = ""+pluralize(verb[0]); break; case "$agent_name": diff -c -r --new-file ds2.0r26/lib/secure/sefun/mud_info.c ds2.0r29/lib/secure/sefun/mud_info.c *** ds2.0r26/lib/secure/sefun/mud_info.c Sun Jun 18 18:01:34 2006 --- ds2.0r29/lib/secure/sefun/mud_info.c Sun Jul 9 22:52:34 2006 *************** *** 27,33 **** string mudlib() { return "Dead Souls"; } ! string mudlib_version() { return "2.0r26"; } int query_host_port() { return __PORT__; } --- 27,33 ---- string mudlib() { return "Dead Souls"; } ! string mudlib_version() { return "2.0r29"; } int query_host_port() { return __PORT__; } diff -c -r --new-file ds2.0r26/lib/secure/sefun/pointers.c ds2.0r29/lib/secure/sefun/pointers.c *** ds2.0r26/lib/secure/sefun/pointers.c Mon May 22 17:19:48 2006 --- ds2.0r29/lib/secure/sefun/pointers.c Wed Jul 5 00:01:06 2006 *************** *** 15,20 **** --- 15,30 ---- return (userp(ob) && member_group(ob, "AMBASSADOR")); } + int elderp(object ob) { + if(!ob) ob = previous_object(); + return (userp(ob) && member_group(ob, "ELDER")); + } + + int testp(object ob) { + if(!ob) ob = previous_object(); + return (userp(ob) && member_group(ob, "TEST")); + } + int archp(object ob) { if(!ob) ob = previous_object(); if(!creatorp(ob)) return 0; *************** *** 27,38 **** } int securep(mixed guy) { if(!guy) guy = previous_object(); ! if(!creatorp(guy)) return 0; if(member_group(guy, "SECURE")) return 1; else return 0; } varargs int creatorp(object ob) { if(!ob) ob = previous_object(); if(!ob || !userp(ob)) return 0; --- 37,59 ---- } int securep(mixed guy) { + mixed dude = guy; if(!guy) guy = previous_object(); ! if(!stringp(guy)) guy = guy->GetKeyName(); ! if(!guy || guy == "") guy = base_name(dude); if(member_group(guy, "SECURE")) return 1; else return 0; } + int assistp(mixed guy) { + mixed dude = guy; + if(!guy) guy = previous_object(); + if(!stringp(guy)) guy = guy->GetKeyName(); + if(!guy || guy == "") guy = base_name(dude); + if(member_group(guy, "ASSIST")) return 1; + else return 0; + } + varargs int creatorp(object ob) { if(!ob) ob = previous_object(); if(!ob || !userp(ob)) return 0; diff -c -r --new-file ds2.0r26/lib/secure/sefun/query_names.c ds2.0r29/lib/secure/sefun/query_names.c *** ds2.0r26/lib/secure/sefun/query_names.c Sat Mar 11 11:20:56 2006 --- ds2.0r29/lib/secure/sefun/query_names.c Sun Jul 9 19:04:30 2006 *************** *** 27,32 **** } int answers_to(string name, object what){ if(member_array(lower_case(name),query_names(what)) != -1) return 1; ! else return 0; } --- 27,59 ---- } int answers_to(string name, object what){ + string *adjs = what->GetAdjectives(); + string *preargs = ({}); + string s1,s2,s3,s4; + int hits; if(member_array(lower_case(name),query_names(what)) != -1) return 1; ! if(!sizeof(adjs)) return 0; ! hits = sscanf(name,"%s %s %s %s",s1, s2, s3, s4); ! //tc("hits: "+hits); ! if(hits < 4) hits = sscanf(name,"%s %s %s",s1, s2, s3); ! //tc("hits: "+hits); ! if(hits < 3) hits = sscanf(name,"%s %s",s1, s2); ! //tc("s1: "+s1); ! //tc("s2: "+s2); ! //tc("s3: "+s3); ! //tc("s4: "+s4); ! if(!hits) return 0; ! hits--; ! if(sizeof(s1)) preargs += ({s1}); ! if(sizeof(s2)) preargs += ({s2}); ! if(sizeof(s3)) preargs += ({s3}); ! if(sizeof(s4)) preargs += ({s4}); ! ! if(member_array(preargs[hits],query_names(what)) == -1) return 0; ! preargs -= ({ preargs[hits] }); ! ! foreach(string prearg in preargs){ ! if(member_array(prearg, adjs) == -1) return 0; ! } ! return 1; } diff -c -r --new-file ds2.0r26/lib/secure/sefun/reload.c ds2.0r29/lib/secure/sefun/reload.c *** ds2.0r26/lib/secure/sefun/reload.c Sun Jun 18 21:26:15 2006 --- ds2.0r29/lib/secure/sefun/reload.c Wed Jul 5 00:01:06 2006 *************** *** 14,20 **** object env; mx = 0; ! //tc("ob: "+identify(ob),"red"); if(!ob) return 0; --- 14,20 ---- object env; mx = 0; ! //tc("ob: "+identify(ob),"red"); if(!ob) return 0; *************** *** 32,38 **** return 0; } ! //tc("ob: "+identify(ob),"green"); if(ob->GetDoor() && sizeof(ob->GetDoor())) ob = load_object(ob->GetDoor()); if(!file_exists(base_name(ob))) filename = base_name(ob)+".c"; --- 32,38 ---- return 0; } ! //tc("ob: "+identify(ob),"green"); if(ob->GetDoor() && sizeof(ob->GetDoor())) ob = load_object(ob->GetDoor()); if(!file_exists(base_name(ob))) filename = base_name(ob)+".c"; *************** *** 45,51 **** write("This object lacks a working init function. Please run initfix on it as soon as possible."); } ! //tc("ob: "+identify(ob),"blue"); if(inherits(LIB_ROOM,ob)){ dudes = get_livings(ob,1); --- 45,51 ---- write("This object lacks a working init function. Please run initfix on it as soon as possible."); } ! //tc("ob: "+identify(ob),"blue"); if(inherits(LIB_ROOM,ob)){ dudes = get_livings(ob,1); diff -c -r --new-file ds2.0r26/lib/secure/sefun/sefun.c ds2.0r29/lib/secure/sefun/sefun.c *** ds2.0r26/lib/secure/sefun/sefun.c Sun Jun 18 16:21:09 2006 --- ds2.0r29/lib/secure/sefun/sefun.c Sun Jul 9 19:04:30 2006 *************** *** 80,85 **** --- 80,92 ---- #include "/secure/sefun/compare_array.c" #include "/secure/sefun/legacy.c" + //void parse_add_rule(string verb, string rule){ + //parse_init(); + //tc("parse_add_rule. verb: "+verb+", rule: "+rule,"white"); + //tell_player("cratylus","parse_add_rule. verb: "+verb+", rule: "+rule); + //tell_player("cratylus","previous_object(): "+identify(previous_object())); + //efun::parse_add_rule(verb, rule); + //} object find_object( string str ){ if((int)master()->valid_apply(({ "SECURE", "ASSIST", "SNOOP_D" }))) return efun::find_object(str); diff -c -r --new-file ds2.0r26/lib/secure/sefun/sefun.h ds2.0r29/lib/secure/sefun/sefun.h *** ds2.0r26/lib/secure/sefun/sefun.h Sun Jun 18 16:21:10 2006 --- ds2.0r29/lib/secure/sefun/sefun.h Fri Jul 7 19:41:43 2006 *************** *** 211,215 **** --- 211,219 ---- void query(mixed arg1, mixed arg2); void personal_log(string str); void add_sky_event(function f); + int assistp(mixed guy); + int elderp(object ob); + int testp(object ob); + string alpha_strip(mixed arg); #endif /* l_sefun_h */ diff -c -r --new-file ds2.0r26/lib/secure/sefun/strings.c ds2.0r29/lib/secure/sefun/strings.c *** ds2.0r26/lib/secure/sefun/strings.c Sun Jun 18 16:21:10 2006 --- ds2.0r29/lib/secure/sefun/strings.c Fri Jul 7 19:41:43 2006 *************** *** 608,613 **** --- 608,627 ---- return 0; } + string alpha_strip(mixed arg){ + string raw, ret; + string *blown; + if(!arg || pointerp(arg)) return ""; + if(!sscanf(arg,"%s",raw)) return ""; + if(!sizeof(raw)) return ""; + blown = explode(raw,""); + ret = ""; + foreach(string element in blown){ + if(alphap(element)) ret += element; + } + return ret; + } + int numericp(mixed arg){ string *alphabet = ({"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}); if(intp(arg)) arg = itoa(arg); diff -c -r --new-file ds2.0r26/lib/secure/verbs/creators/force.c ds2.0r29/lib/secure/verbs/creators/force.c *** ds2.0r26/lib/secure/verbs/creators/force.c Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/secure/verbs/creators/force.c Sun Jul 9 19:04:30 2006 *************** *** 0 **** --- 1,43 ---- + #include + + inherit LIB_VERB; + + static void create() { + verb::create(); + SetVerb("force"); + SetRules("LIV STR", "LIV to STR"); + SetErrorMessage("Force whom to do what?"); + SetHelp("Syntax: \n" + " \n" + "Allows you to command some living things to do " + "your bidding."); + } + + mixed can_force_liv_to_str(string str) { return 1; } + + mixed can_force_liv_str(string str) { + return can_force_liv_to_str(str); + } + + mixed do_force_liv_to_str(object target, string cmd) { + object who = this_player(); + + if(!who) return 0; + if(archp(target) && !securep(who)){ + who->eventPrint(target->GetName()+" shakes "+possessive(target)+ + " head and forces you to dest yourself."); + tell_room(environment(who), who->GetName()+" dests "+objective(who)+ + "self while trying to pull a foolish joke on "+target->GetName()+".", who); + tell_player(target,who->GetName()+" tried to force you to "+cmd); + who->eventDestruct(); + return 1; + } + target->eventPrint(who->GetName() + " forces you to: " + cmd); + who->eventPrint("You force " + target->GetShort() + " to: " + cmd); + target->eventForce(cmd); + return 1; + } + + mixed do_force_liv_str(object ob, string str) { + return do_force_liv_to_str(ob, str); + } diff -c -r --new-file ds2.0r26/lib/verbs/creators/copy.c ds2.0r29/lib/verbs/creators/copy.c *** ds2.0r26/lib/verbs/creators/copy.c Wed May 24 12:05:37 2006 --- ds2.0r29/lib/verbs/creators/copy.c Fri Jul 7 19:41:43 2006 *************** *** 41,47 **** write("in your workroom."); return 1; } ! if(userp(ob)){ write("No."); return 1; --- 41,48 ---- write("in your workroom."); return 1; } ! //debug("str: ",str); ! //debug("path_prefix(str): ",path_prefix(str)); if(userp(ob)){ write("No."); return 1; *************** *** 51,57 **** targetfile = ""; if(last(str,2) != ".c") str += ".c"; str = absolute_path((string)this_player()->query_cwd(), str); ! if( !directory_exists(path_prefix(str)) ) return "Directory not found."; sourcefile = base_name(ob)+".c"; targetfile = str; --- 52,63 ---- targetfile = ""; if(last(str,2) != ".c") str += ".c"; str = absolute_path((string)this_player()->query_cwd(), str); ! //debug("str: ",str); ! //debug("path_prefix(str): ",path_prefix(str)); ! if( !directory_exists(path_prefix(str)) ) { ! write("Directory not found."); ! return 1; ! } sourcefile = base_name(ob)+".c"; targetfile = str; *************** *** 74,80 **** } mixed do_copy_str(string str) { ! string tmp, new_room; mixed source_update; object staff; staff = present("tanstaafl",this_player()); --- 80,86 ---- } mixed do_copy_str(string str) { ! string str2, tmp, new_room; mixed source_update; object staff; staff = present("tanstaafl",this_player()); *************** *** 84,93 **** write("in your workroom."); return 1; } if(last(str,2) != ".c") str += ".c"; ! str = absolute_path((string)this_player()->query_cwd(), str); ! if( !file_exists(str) ) return "File " + str + " not found."; else if( !(tmp = read_file(str)) || !tmp || tmp == ""){ write("Unable to read file " + str + "."); return 1; --- 90,115 ---- write("in your workroom."); return 1; } + //debug("str: ",str,"yellow"); + str2 = str; + str = absolute_path((string)this_player()->query_cwd(), str); + //debug("str: ",str,"yellow"); + + //debug("path_prefix(str): ",path_prefix(str),"green"); if(last(str,2) != ".c") str += ".c"; ! //debug("str: ",str,"yellow"); ! ! if( !file_exists(str) ){ ! str = path_prefix(base_name(environment(this_player())))+"/"+str2; ! if(last(str,2) != ".c") str += ".c"; ! } ! ! if( !file_exists(str) ){ ! write("Directory not found."); ! return 1; ! } ! else if( !(tmp = read_file(str)) || !tmp || tmp == ""){ write("Unable to read file " + str + "."); return 1; diff -c -r --new-file ds2.0r26/lib/verbs/items/put.c ds2.0r29/lib/verbs/items/put.c *** ds2.0r26/lib/verbs/items/put.c Sun Jun 18 16:21:10 2006 --- ds2.0r29/lib/verbs/items/put.c Sat Jul 8 23:31:00 2006 *************** *** 134,156 **** mixed do_put_wrd_wrd_word_obj(string num, string curr, mixed wort, object ob) { object pile, env; int amt; - //tc("ob: "+identify(ob),"yellow"); - //tc("wort: "+wort,"yellow"); if(wort == "on") wort = "onto"; if(wort == "in") wort = "into"; - //tc("wort: "+wort,"yellow"); if(wort == "onto" && !inherits( LIB_SURFACE, ob ) ) { - //tc("wtf1"); write("That isn't a load-bearing surface."); return 1; } if(wort == "into" && inherits( LIB_SURFACE, ob ) ) { - //tc("wtf2"); write("That's a surface. Try \"put on\""); return 1; } amt = to_int(num); env = environment(this_player()); --- 134,157 ---- mixed do_put_wrd_wrd_word_obj(string num, string curr, mixed wort, object ob) { object pile, env; int amt; if(wort == "on") wort = "onto"; if(wort == "in") wort = "into"; if(wort == "onto" && !inherits( LIB_SURFACE, ob ) ) { write("That isn't a load-bearing surface."); return 1; } if(wort == "into" && inherits( LIB_SURFACE, ob ) ) { write("That's a surface. Try \"put on\""); return 1; } + if((inherits(LIB_SIT,ob) && sizeof(ob->GetSitters())) || + (inherits(LIB_LIE,ob) && sizeof(ob->GetLiers()))){ + write("There appears to be someone blocking your access."); + return 0; + } + amt = to_int(num); env = environment(this_player()); diff -c -r --new-file ds2.0r26/lib/verbs/players/follow.c ds2.0r29/lib/verbs/players/follow.c *** ds2.0r26/lib/verbs/players/follow.c Fri May 12 21:15:43 2006 --- ds2.0r29/lib/verbs/players/follow.c Sun Jul 9 19:04:30 2006 *************** *** 13,19 **** ::create(); SetVerb("follow"); SetRules("", "LIV"); ! SetErrorMessage("Who would you like to follow?"); SetHelp("Syntax: follow\n" " follow LIV\n" "\n" --- 13,19 ---- ::create(); SetVerb("follow"); SetRules("", "LIV"); ! SetErrorMessage("Whom would you like to follow?"); SetHelp("Syntax: follow\n" " follow LIV\n" "\n" *************** *** 40,46 **** // Format follow string. if(this_player()->CanLead() && leader = this_player()->GetLeader()) { tmp = "You are "; ! if(leader->GetAllowed(this_player())) tmp += "following"; else tmp += "trailing"; tmp += " " + leader->GetName() + ".\n"; } --- 40,46 ---- // Format follow string. if(this_player()->CanLead() && leader = this_player()->GetLeader()) { tmp = "You are "; ! if(leader->GetFollowed(this_player())) tmp += "following"; else tmp += "trailing"; tmp += " " + leader->GetName() + ".\n"; } *************** *** 53,59 **** // Format lead string. tmp += "You are leading "; obs = map( ! filter(followers, (:this_player()->GetAllowed($1):)), (:$1->GetName():)); size = sizeof(obs); if(size) tmp += conjunction(obs); --- 53,59 ---- // Format lead string. tmp += "You are leading "; obs = map( ! filter(followers, (:this_player()->GetFollowed($1):)), (:$1->GetName():)); size = sizeof(obs); if(size) tmp += conjunction(obs); *************** *** 63,69 **** // Format evasion string. tmp += "You are evading "; obs = map( ! filter(followers, (:!this_player()->GetAllowed($1):)), (:$1->GetName():)); size = sizeof(obs); if(size) tmp += conjunction(obs); --- 63,69 ---- // Format evasion string. tmp += "You are evading "; obs = map( ! filter(followers, (:!this_player()->GetFollowed($1):)), (:$1->GetName():)); size = sizeof(obs); if(size) tmp += conjunction(obs); *************** *** 82,87 **** --- 82,88 ---- if(leader = this_player()->GetLeader()) { leader->RemoveFollower(this_player()); this_player()->eventPrint("You stop trailing " + leader->GetName() + "."); + return 1; } if(member_array(this_player(), ob->AddFollower(this_player())) == -1) diff -c -r --new-file ds2.0r26/lib/verbs/players/lead.c ds2.0r29/lib/verbs/players/lead.c *** ds2.0r26/lib/verbs/players/lead.c Fri May 12 21:15:43 2006 --- ds2.0r29/lib/verbs/players/lead.c Sat Jul 8 23:31:00 2006 *************** *** 13,19 **** verb::create(); SetVerb("lead"); SetRules("LIV"); ! SetErrorMessage("Who would you like to lead?"); SetHelp("Syntax: lead LIVING\n" "\n" "Allows one to assist a living being who is " --- 13,19 ---- verb::create(); SetVerb("lead"); SetRules("LIV"); ! SetErrorMessage("Whom would you like to lead?"); SetHelp("Syntax: lead LIVING\n" "\n" "Allows one to assist a living being who is " diff -c -r --new-file ds2.0r26/lib/www/articles/copyright.html ds2.0r29/lib/www/articles/copyright.html *** ds2.0r26/lib/www/articles/copyright.html Sun Jun 18 16:08:31 2006 --- ds2.0r29/lib/www/articles/copyright.html Wed Jul 5 00:01:06 2006 *************** *** 9,15 ****
Intellectual Property and Dead Souls

When I began work on Dead Souls, I hadn't
thought that I'd have much to worry about, in terms
of intellectual property, or IP. Given that Dead Souls
was itself "public domain" software, it didn't seem
like it would be an issue. Little did I know!

There have been some areas of concern for
folks in this regard, and this article is intended
to clarify my actions and intent when it comes to
Dead Souls and IP. The main issues break down into
three main categories:

Intellectual Property and Dead Souls

updated 23 June 2006


When I began work on Dead Souls, I hadn't
thought that I'd have much to worry about, in terms
of intellectual property, or IP. Given that Dead Souls
was itself "public domain" software, it didn't seem
like it would be an issue. Little did I know!

There have been some areas of concern for
folks in this regard, and this article is intended
to clarify my actions and intent when it comes to
Dead Souls and IP. The main issues break down into
three main categories:

Descartes
in the late 1990's.
DS 1.1 was placed into the public domain, meaning
that Descartes released all copyright to the lib,
making it freely distributable in any form by any
one in any way, including commercially.

This was in stark contrast to the strict
reservation of copyright for his other mudlib, Nightmare IV.
Nightmare IV remained under his copyright, and it
further had a highly restrictive license which
imposed limits to its use beyond that which is normally
enforced through copyright law.

Descartes vigorously defended his NM IV licensing
and copyright, and to this day old-timers in the LP
mud community look back on Descartes's withdrawal of the
NM IV lib from public distribution with some bemusement.
Whatever one thinks of his motives, it must be said that
Descartes was effective at squelching the unauthorized
distribution of the Nightmare IV lib.

This has left some people with the impression
that Dead Souls is somehow tainted by restrictive
licensing. For Dead Souls 1.1, this is not true. DS 1.1
can be used in any way one sees fit.

Dead Souls 1.2 and above, however, are not public
domain. They are GPL, meaning that whatever one finds
in Dead Souls 1.x to 2.x that is *not* found in DS 1.1
does in fact retain copyright and its distribution is
subject to the requirements of the GPL.

Translated into layman's terms, this means that
the current versions of Dead Souls cannot be distributed
unless their source code is also distributed, they are
otherwise entirely free to be distributed whether
commercially or otherwise. The experienced LP coder at
this point will object: "Hey, that doesn't make sense! LPC
is an interpreted language, so distributing it is de facto
distribution of code!"

From a technical standpoint, it's pretty senseless
(with some exceptions) to GPL Dead Souls. The lib itself
runs in the form of plain text..there's no way to hide
the source even if you wanted to. In this sense, GPL'ing
DS is meaningless.

However, I wanted to distribute DS in Windows
binary format, which meant in this case using Cygwin. To
use Cygwin, I needed to comply with their licensing which
as GPL made it a prerequisite that Cygwin was to be distributed
porting other software only if that software complied with
GPL-style licensing. By making Dead Souls explicitly
GPL, I could comply with Cygwin licensing and distribute
the driver binary I created.

To clarify, whatever is in Dead Souls now that
was in Dead Souls 1.1 is still public domain software.
Whatever is in Dead Souls now that was not in Dead Souls
1.1 is copyrighted and licenced under the GPL.


The controversy over Cygwin GPL violation

In early 2006, one of the sites that provided
downloads of Dead Souls to the public abruptly pulled it
from distribution. Apparently someone had complained
to the site administrator that Dead Souls was in violation
of the GPL, and it was improper to host it.

This was a shock to me, because I thought I
had been scrupulous in my adherence to Cygwin policy.

To summarize, there was a Windows version of DS
which contained a pre-compiled Windows executable, to
permit the mud to run in Windows. This executable was
created in the Cygwin environment, and the
only way it would run on a Windows computer is if that
computer had some files called dll's, or "dynamic link
libraries" from the Cygwin environment. Since the point
was sharing the lib with people unwilling or unable to
compile for Windows, including the dll's along with the
executable seemed like the reasonable thing to do.

I examined Cygwin's policy on distributing their
dll's, and based on my interpretation, it seemed ok. It
turns out my interpretation of their licensing was incorrect.

What I thought they meant was that if you have
possibly modified their dll's, you cannot distribute them unless
you also distribute the source code.

What they actually meant was that whether or not
you had modified the dll's, you cannot distribute them unless
you also distribute the source code.
 
I queried the Cygwin licensing discussion list and
searched their archives until I found an example like Dead Souls.
A software company used Cygwin dll's and distributed them
without source, but when told they were in violation of the
Cygwin license, they simply added the dll's source code to their
download page, and this satisfied the Cygwin licensing folks.

I changed the download pages for Dead Souls to
make available the source code for the Cygwin dll's I was
distributing, and the site administrator allowed the
Dead Souls downloads to continue.

That's it. That's the whole story. Some folks have
chosen to inflate this event into allegations of Dead Souls
containing "stolen" code, which is as baffling to me as it
is untrue.

Descartes in the late 1990's.
DS 1.1 was placed into the public domain, meaning
that Descartes released all copyright to the lib,
making it freely distributable in any form by any
one in any way, including commercially.

This was in stark contrast to the strict
reservation of copyright for his other mudlib, Nightmare IV.
Nightmare IV remained under his copyright, and it
further had a highly restrictive license which
imposed limits to its use beyond that which is normally
enforced through copyright law.

Descartes vigorously defended his NM IV licensing
and copyright, and to this day old-timers in the LP
mud community look back on Descartes's withdrawal of the
NM IV lib from public distribution with some bemusement.
Whatever one thinks of his motives, it must be said that
Descartes was effective at squelching the unauthorized
distribution of the Nightmare IV lib.

This has left some people with the impression
that Dead Souls is somehow tainted by restrictive
licensing. For Dead Souls 1.1, this is not true. DS 1.1
can be used in any way one sees fit.

Dead Souls 1.2 and above, however, are not public
domain. They are GPL, meaning that whatever one finds
in Dead Souls 1.x to 2.x that is *not* found in DS 1.1
does in fact retain copyright and its distribution is
subject to the requirements of the GPL.

Translated into layman's terms, this means that
the current versions of Dead Souls cannot be distributed
unless their source code is also distributed, they are
otherwise entirely free to be distributed whether
commercially or otherwise. The experienced LP coder at
this point will object: "Hey, that doesn't make sense! LPC
is an interpreted language, so distributing it is de facto
distribution of code!"

From a technical standpoint, it's pretty senseless
(with some exceptions) to GPL Dead Souls. The lib itself
runs in the form of plain text..there's no way to hide
the source even if you wanted to. In this sense, GPL'ing
DS is meaningless.

However, I wanted to distribute DS in Windows
binary format, which meant in this case using Cygwin. To
use Cygwin, I needed to comply with their licensing which
as GPL made it a prerequisite that Cygwin was to be distributed
porting other software only if that software complied with
GPL-style licensing. By making Dead Souls explicitly
GPL, I could comply with Cygwin licensing and distribute
the driver binary I created.

To clarify, whatever is in Dead Souls now that
was in Dead Souls 1.1 is still public domain software.
Whatever is in Dead Souls now that was not in Dead Souls
1.1 is copyrighted.

UPDATE: 23 June 06

Dead Souls is not GPL. Due to the incessant nitpicking
of pedants who are overconcerned with software licensing, I
am revoking GPL. Dead Souls is copyrighted, and you can download
it and use it under no obligation to share anything. However,
I retain distribution rights. When I have nothing better to
think about I will decide on some "official" license to slap
on it, or come up with my own.

But all I want to do is code the greatest LP lib ever,
and I am just through with thinking about licensing.

My guess is that some licensing Nazi will read this and
try to find a way to make my life difficult because I revoked
GPL. There is just no pleasing some people. Just leave me alone,
please. Can't you just leave me alone?


The controversy over Cygwin GPL violation

In early 2006, one of the sites that provided
downloads of Dead Souls to the public abruptly pulled it
from distribution. Apparently someone had complained
to the site administrator that Dead Souls was in violation
of the GPL, and it was improper to host it.

This was a shock to me, because I thought I
had been scrupulous in my adherence to Cygwin policy.

To summarize, there was a Windows version of DS
which contained a pre-compiled Windows executable, to
permit the mud to run in Windows. This executable was
created in the Cygwin environment, and the
only way it would run on a Windows computer is if that
computer had some files called dll's, or "dynamic link
libraries" from the Cygwin environment. Since the point
was sharing the lib with people unwilling or unable to
compile for Windows, including the dll's along with the
executable seemed like the reasonable thing to do.

I examined Cygwin's policy on distributing their
dll's, and based on my interpretation, it seemed ok. It
turns out my interpretation of their licensing was incorrect.

What I thought they meant was that if you have
possibly modified their dll's, you cannot distribute them unless
you also distribute the source code.

What they actually meant was that whether or not
you had modified the dll's, you cannot distribute them unless
you also distribute the source code.
 
I queried the Cygwin licensing discussion list and
searched their archives until I found an example like Dead Souls.
A software company used Cygwin dll's and distributed them
without source, but when told they were in violation of the
Cygwin license, they simply added the dll's source code to their
download page, and this satisfied the Cygwin licensing folks.

I changed the download pages for Dead Souls to
make available the source code for the Cygwin dll's I was
distributing, and the site administrator allowed the
Dead Souls downloads to continue.

That's it. That's the whole story. Some folks have
chosen to inflate this event into allegations of Dead Souls
containing "stolen" code, which is as baffling to me as it
is untrue.

+ + + + security bug forum chat + + + tacitus - 2006/06/17 05:48 
+
+ I'm all for healthy competition + and needling each other. I think
+ anyone who knows me knows I'm + anything but thin-skinned.
+ I enjoy a good romp either on gjs + or on justrage, or whatever.
+
+ This thing, though, crossed the + line between rough play
+ and actual harm.
+
+ I figured Tacitus would be + insufferably smug if he found
+ the bug he was looking for, but I + figured that was a small
+ price to pay for getting help + securing DS. What I did
+ not count on was him taking it + upon himself to delete
+ log files.
+
+ This is a serious problem, + because he was messing with
+ security, and if I can't tell + what he did, I have to
+ stop everything and reconstruct + the events by hand.
+
+ Whether it was malicious is + actually beside the point.
+ Either he's untrustworthy because + he was concealing bad
+ behavior, or he's untrustworthy + because he doesn't know
+ better than to tromp around + someone's logs as he pleases,
+ without so much as a hint of his + intentions to the
+ owner.
+
+ Either way, it was a breach of + trust I did not expect
+ from someone I've been supporting + as a leader in the
+ community.
+
+ I've been granted guest creator + and sometimes even guest
+ admin privileges on other + people's muds, and I have
+ never done anything but exactly + what I've announced
+ and only with permission, because + it's not my mud
+ and I understand that. This is + basic. It's obvious.
+ In someone else's house, you ask + before you perform
+ potentially irreversible changes, + or you can just
+ consider yourself a boor.
+
+ So there's that.
+
+ According to Tacitus he attempted + to delete logs without
+ asking permission out of a + concern that other people
+ might happen upon them and learn + the exploit. Aside
+ from the obvious objection that + he could have just
+ told me so I could decide for + myself, is the bizarre
+ fact that he went on gjs + intergossip to announce there
+ his achievement, and allowed + thespread of information about how
+ he did it. Any casual reader of + the gjs i3 log is
+ now in full possession of all the + details needed to
+ compromise a Dead Souls mud, if + given Creator status.
+
+ How this squares with his stated + intention of protecting
+ the community by deleting my logs + I can't say.
+
+ There are some folks out there + who find exploits in
+ commercial software, and share + the information
+ with the public in an attempt to + help people get
+ ahead of the curve. Even assuming + this is not
+ dangerous, it is common for + professional, responsible
+ programmers who find serious + flaws to give the
+ manufacturer a few days or weeks + to develop a
+ patch before outing the info. As + a colleague, this
+ is the least I would have + expected.
+
+ Instead I'm now spending what + little of the weekend
+ I had for myself reconstructing + free space to
+ find potentially deleted files, + and exhaustively
+ nailing down each exploit and + subexploit related to
+ this incident. Just because + Tacitus couldn't contain
+ his glee and pride at rooting me, + and couldn't
+ give me a couple of days to deal + with it
+ in a more deliberate and measured + way.
+
+ Well, Tacitus, you win. The big + bad Dead Souls
+ juggernaut had feet of clay, + after all.
+
+ However, you've lost any trust I + had in you, any
+ good will. Maybe it will change, + but at the moment
+ I just don't see myself feeling + up to dealing
+ with you. You didn't have to do + it this way.
+ I hope the schadenfreude was + worth it.
+
+ When you came back from watching + your
+ movie, this was your message:
+
+ Tacitus@TimMUD + <intergossip> How is that audit coming?
+
+
+ It's coming along fine. Thanks.
+
+ -Crat
+  
+

+
+ Re:tacitus - 2006/06/17 06:00
+
+ I think Cratylus made some very + valid points however I think we all know that I wasn't trying to be + malicious - I was simply excited by my discovery. Furthermore, you told + me you were snooping and then I paged the log file and then proceeded + to delete (However, either the access file hadn't reparsed or you had + already removed me from the arch group so it failed) the log file that + contained the commands (eval and call logs) I used to find the exploit. + From today's events, I can only conclude we didn't truly realize the + lack of trust we had in each other in the first place or you are trying + to use this as some sort of publicity stunt.
+
+ As for the information being + released on intermud, I did not release the information directly. + Rather Duuk was cleaver enough to pry enough out of him to figure it + out on his own and then proceed to make fun of you - I can see how your + feelings can be a bit hurt.
+
+ I know if this happened to my + lib, I'd be very much embarassed too and I can understand why you are + making this post. I humbly appologize.
+
+ P.S. The audit comment was to + Hellmonger because he joking said that he'd audit my mudlib for me. If + you know this and that means that you are now auditing my mudlib, I + look forward to the results.
+
+ Post edited by: somerville32, at: + 2006/06/17 06:02 Tacitus
+ Executive Director
+ Research, Education, and + Development
+ LPUniversity Foundation
+
+

+
+ Re:tacitus - 2006/06/17 + 06:18 
+
+ For the record, I don't remember + saying anything about
+ watching you. While you were + messing with my lib, I was
+ in the middle of helping Samael. + That was the level of
+ trust I had in you. When you + started crowing about your
+ success, I started snooping you, + and saw you trying
+ to delete logs. You can imagine + my dismay. Given
+ that you were admin, were + deleting logs without telling me,
+ and I didn't know what you'd do + next, I ridded you on the spot
+ and locked the mud, but alas, + you'd already made yourself
+ an elder, so you recreated your + character and logged back
+ in. Not knowing what you *had* + done or what you *planned*
+ to do, I killed the mud process, + unmounted the filesystem,
+ and began the tedious process of + intrusion forensics.
+
+ You really don't need to suggest + I feel hurt because of Duuk.
+
+ I feel betrayed because of *you*.
+
+ You seem intent on provoking me + by claiming that my
+ statements are for some purpose + other than telling the truth.
+
+ I would suggest you read my + statements as declarations
+ of what I believe to be true, + regardless of how uncomfortable
+ that might make you.
+
+ -Crat
+ + diff -c -r --new-file ds2.0r26/lib/www/articles/patches.html ds2.0r29/lib/www/articles/patches.html *** ds2.0r26/lib/www/articles/patches.html Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/www/articles/patches.html Wed Jul 5 00:01:06 2006 *************** *** 0 **** --- 1,22 ---- + + + + + Patches?!? + + + + +
Patches?!?


For the impatient, you may skip down to the "Summary"
section at the bottom of this post.


The Disclaimer
The first thing to understand is that I don't profit
from DS, and I'm the only guy developing the core lib.
I'm not saying this because I want sympathy. I'm
saying it because this makes me have a very tight
focus on what I can and can't do within the short
time I've been granted here on Earth.

My goal is to make Dead Souls the best, most kick-ass
LPC lib ever. I interpret this to mean that when I
see a flaw, or someone else points one out, I want
it fixed. And, well, the fixing falls to me.


The History
Over the past year, what this has meant is that I
fix a given version, and after a while of fixes
accumulating, I declare it to be a new release and
off it goes, into the world. At first this caused a
lot of grumbling, because it meant people had to
reinstall from scratch every time I made a release,
and this was a bit much for many people.

It occurred to me that I could compile a package that
had only the files that changed between releases. I
put this together, and people seemed to really like
being able to upgrade from one release to another,
without a full reinstall. Over time, this system
has been tweaked and refined somewhat, but in the
end, it's roughly the same type of thing it was back
when I produced the first one: a bunch of files.


The Mechanics
The patching process is just as primitive as it
sounds. You uncompress these files and copy them
over your existing mud. Simple. Efficient.

Player files, directories, and domains that are
created by you are left untouched.

For some people this system is problematic. Some folks
are proficient at modifying lib code, and if they
just overwrite their mud with the contents of a patch,
they might find that their lib work has been clobbered. This
would be bad. That is why my patch instructions
strenuously remind people to back up the current mud
before patching it.

There is no practical solution for this problem that
I can see. Because I am just one guy, and my goal
is lib code, and not patch-process-design, I have
decided to leave things as they are. In theory I could
write code that would analyze and modify files as
needed, rather than simply have the owner overwrite.
However, this is a lot more complicated than it sounds
to implement in LPC within the lib, and it is also
non-trivial to implement this at the OS level, given
that the process would have to work on multiple different
platforms.

It's my opinion that people sophisticated enough to
need a more specialized patching system are
sophisticated enough to work around my shortcomings
in this area. Indeed, I've heard of folks who just
download the complete new version, run diffs against the
old one, and then pick and choose what to add.

For now and the foreseeable future, upgrades are just
a Big Dumb Ball of Files...with one exception.

Each patch includes a file called /secure/daemon/update.c
which carries out special functions that are not dealt
with by just overwriting files. When you reboot the mud,
update.c will do things like remove broken/dangerous files,
rename files with incorrect names, and modify text in
files (such as config.h) which should not be overwritten
but need to be changed.


The Philosophy and Controversy
Believe it or not, I've had people become irrationally
angry at how often I make releases. Not just "That darn
Crat is driving me crazy", but actual, unhinged flaming
well beyond any reasonable context.

Don't believe me? Check it out for yourself:

http://www.justrage.com/article.php?story=cratylus_dead_souls_mudlib


It *is* true that I'm averaging a release every week
or two. The person is correct in that there are a lot
of bugs to fix, and that releases happen much, much
more often than they do for other muds.

I have no defense against this charge. All I can do
is explain the reason for it, and hope it is justification
enough.

When someone tells me Dead Souls has a bug, I want to
help them. I want to fix it. I feel responsible to the
mud community to do what I can to fix whatever problems
they've run into because they've adopted the lib I
wanted them to. This is probably irrational on my part,
and if I'm lucky, I'll stop feeling this way sometime
soon. But until I do, I feel driven to be a responsive
lib coder, and I fix stuff. And I release it.

The question is, "If Dead Souls is so lame it needs
constant patching, shouldn't you kill it?"

The thing is, Dead Souls is the best LPmud lib out
there that I know of, *right now*. If the standard is
going to be perfection, then there's no lib out there
that should be available. There's no LPC mudlib
out there that you can download that is as featured,
solid, widely adopted, and supported as Dead Souls. If
the criteria for killing a lib is that it's not
perfect, and if Dead Souls is among the libs to be killed,
then just about everything needs a good flush.

It should be noted that Dead Souls doesn't *need*
constant patching. With the exception of security
fixes, any patch, upgrade, or hotfix is entirely
optional. You can stop patching and upgrading at
any time, and strike out in your own direction with
the lib. And as a matter of fact, I'd be tickled
pink if you did. The sprouting of evolutionary branches
off Dead Souls would delight me, because it would be
good evidence that I have begun something that's
going to continue beyond what I've done with my own
little brain.


Summary

* Yes, I'm a bit defensive on this topic. To me, "there
are too many updates" sounds a lot like "stop working on
the lib", which (I think, understandably) makes me testy.

* Dead Souls is fine just the way it is. If you don't
want to update, don't. As it is, right now, it's better
than any other LP lib I know of that you can download.

* If you do update, make sure you back up your mud.

* If you have ideas about how I can make the update
process less painful, KEEP THEM TO YOURSELF. I am not in
the business of patch/upgrade design, and, I'm sorry,
but I am not going to spend more time on it. All I
want to do is make DS the best ever.

* If you want to design and write a less painful upgrade method
that I can implement on DS, that's great. Let me know
about it so that I can avoid doing anything that makes
your work more difficult. Just don't expect me to work on
it *with* you.


I know this sounds a bit harsh...I hope you folks know
me well enough that you'll forgive a bit of the rudeness.

What it boils down to is a decision on where my time is
spent, and I'm pretty much sticking to my original plan.

For what it's worth, the vast majority of upgraders that
follow the patch install instructions report nothing
but a smooth process.


Dead Souls Homepage

+ + diff -c -r --new-file ds2.0r26/lib/www/articles/tacitus.html ds2.0r29/lib/www/articles/tacitus.html *** ds2.0r26/lib/www/articles/tacitus.html Sun Jun 18 16:08:32 2006 --- ds2.0r29/lib/www/articles/tacitus.html Wed Jul 5 00:01:06 2006 *************** *** 0 **** --- 1,18 ---- + + + + + Tacitus + + + + +
Tacitus

Hey folks,

I'm getting the drift that some people feel there is some
sort of political big deal going on between Tacitus and me.

I just wanted to take this opportunity to clarify things
a bit.

Yes, I *do* have a problem with Tacitus-the-person, who has
personally offended me, put people at risk, and been an
all around source of unpleasantness for me lately.

However, I am not interested in, nor do I have the time for,
some kind of Kyndig/Samson style feud. I appreciate all the
supportive emails, and the kind words both on- and off- the
record. But in the end, all I want to do is make Dead Souls
the best LPC lib ever, and getting into a juvenile pissing match
is exactly the sort of thing that makes that difficult.

So, be aware of the fact that I want people to contribute to his
site, and I want LPU to be successful, because that is an
overall plus for Dead Souls. Please keep up the community
participation.

Whatever I've been doing lately to express my displeasure
with Tacitus has nothing to do with you guys, and I am not
interested in ganging up on anyone. Please just let me
be angry with Tacitus, and carry on with your business.

Thanks.

-Crat


Update 27 June 2006

People who missed the original event have been
puzzled over what I'm talking about here. For their
benefit, I'm posting three consecutive messages from
then which will help illustrate the problem. They
were originally posted on the LPU site.

Dead Souls Homepage

+ + diff -c -r --new-file ds2.0r26/lib/www/articles.html ds2.0r29/lib/www/articles.html *** ds2.0r26/lib/www/articles.html Sun Jun 18 16:08:33 2006 --- ds2.0r29/lib/www/articles.html Wed Jul 5 00:00:59 2006 *************** *** 9,20 ****
Dead Souls Articles

No, this page isn't about parts of speech. Occasionally
I'll wax long-winded, and my rantings can qualify as free-standing
articles on a subject. This page allows me to separate that from
the rest of the site, so you can read my rants if you want,
or avoid them if you prefer.

These articles tend to be opinions, not technical
docs, so you can skip them without feeling pain.

If folks submit articles they've written they'd like
me to post here, I'll gladly accept them for consideration.


The Dead Souls and LPUniversity libs

Why New Muds Should Use Dead Souls

Is OLC Good for LPC?

Intellectual Property and Dead Souls

Kyndig and Dead Souls


Dead Souls Homepage

--- 9,21 ----
Dead Souls Articles

No, this page isn't about parts of speech. Occasionally
I'll wax long-winded, and my rantings can qualify as free-standing
articles on a subject. This page allows me to separate that from
the rest of the site, so you can read my rants if you want,
or avoid them if you prefer.

These articles tend to be opinions, not technical
docs, so you can skip them without feeling pain.

If folks submit articles they've written they'd like
me to post here, I'll gladly accept them for consideration.



Why New Muds Should Use Dead Souls

Is OLC Good for LPC?

Intellectual Property and Dead Souls

Kyndig and Dead Souls

Patches?!?

Tacitus


Dead Souls Homepage

diff -c -r --new-file ds2.0r26/lib/www/downloads.html ds2.0r29/lib/www/downloads.html *** ds2.0r26/lib/www/downloads.html Sun Jun 18 16:08:34 2006 --- ds2.0r29/lib/www/downloads.html Wed Jul 5 00:00:59 2006 *************** *** 3,17 **** ! Dead Souls FAQ
Useful Downloads and Applications

Written by Cratylus @ Frontiers, May 2006

No program exists in a vacuum. For many people, their
operating systems generally provide all the software they
need to operate Dead Souls
adequately. But sometimes there
is just a better way.

In the spirit of the poor college student I was when I
started mudding, I will try to include only freeware or free
shareware apps here.

Windows editors

Windows clients

UNIX clients


Windows editors:

The #1 problem in Windows is that the default plaintext
editor, Notepad, produces text that is not 100% compatible with the
mud. Windows plaintext and UNIX plaintext differ, believe it
or not. If you use notepad for editing mudos.cfg, for example,
your mud is likely to just fail to boot. This is because it
can no longer read the "incorrectly" formatted file.

The other big problem with Notepad and Wordpad is that
they often add formatting and characters to text files that
make them very ugly and hard to read from inside the mud.

The solution is to use a text editor that can save in
UNIX text format. The following URLs point to editors that I
have been told will do a good job of this. I can't vouch for
them, as they are 3rd party apps and I've never tested them, but
I am assured they are very good for this.

Notepad++ http://notepad-plus.sourceforge.net/uk/site.htm
! Dead Souls Downloads
Useful Downloads and Applications

Written by Cratylus @ Frontiers, June 2006

No program exists in a vacuum. For many people, their
operating systems generally provide all the software they
need to operate Dead Souls
adequately. But sometimes there
is just a better way.

In the spirit of the poor college student I was when I
started mudding, I will try to include only freeware or free
shareware apps here.

Windows editors

Windows clients

UNIX clients

Mudsbuilder client stuff


Windows editors:

The #1 problem in Windows is that the default plaintext
editor, Notepad, produces text that is not 100% compatible with the
mud. Windows plaintext and UNIX plaintext differ, believe it
or not. If you use notepad for editing mudos.cfg, for example,
your mud is likely to just fail to boot. This is because it
can no longer read the "incorrectly" formatted file.

The other big problem with Notepad and Wordpad is that
they often add formatting and characters to text files that
make them very ugly and hard to read from inside the mud.

The solution is to use a text editor that can save in
UNIX text format. The following URLs point to editors that I
have been told will do a good job of this. I can't vouch for
them, as they are 3rd party apps and I've never tested them, but
I am assured they are very good for this.

Notepad++ http://notepad-plus.sourceforge.net/uk/site.htm
MudMagic http://www.mudmagic.com/mud-client/linux_download


+ Mudsbuilder + client stuff
+
+     There's a GUI client for building LPC areas called + Mudsbuilder.
+ Download + it from Sourceforge and see if it suits you. There is
+ also a related Windows + app. You can use this template file to create +
+ Dead Souls rooms in the Windows app(Thanks Saquivor!). You'll have
+ to modify the template a bit to get it working on the Linux app.
+
+     See the LPUniversity + forums posts from Saquivor.
+
+
The end.

Dead Souls Homepage
diff -c -r --new-file ds2.0r26/lib/www/ds-admin-faq.html ds2.0r29/lib/www/ds-admin-faq.html *** ds2.0r26/lib/www/ds-admin-faq.html Sun Jun 18 16:08:35 2006 --- ds2.0r29/lib/www/ds-admin-faq.html Wed Jul 5 00:00:59 2006 *************** *** 8,15 **** !
Dead Souls Admin FAQ, v3.3

Written by Cratylus @ Frontiers, October 2005
Updated June 2006

Note: commands are displayed in boldface, like this: ls -a

What's this FAQ about?


The point of this document is to orient a new admin in
Dead Souls 2. Starting a MUD with a lib that is completely new to
you can be confusing and discouraging. Hopefully this FAQ will
make the experience less difficult.


!
Dead Souls Admin FAQ, v3.4

Written by Cratylus @ Frontiers, October 2005
Updated June 2006

Note: commands are displayed in boldface, like this: ls -a

What's this FAQ about?


The point of this document is to orient a new admin in
Dead Souls 2. Starting a MUD with a lib that is completely new to
you can be confusing and discouraging. Hopefully this FAQ will
make the experience less difficult.


86 Where are read/write restrictions kept?

87 I need to test day/night descriptions, but I can't wait around all day.

88 How can I change the default prompt? Can I make it dynamic?

89 What is "unguarded"?

90 Is intermud communication secure?



How do I start?

The first thing to do is follow the installation FAQ
to get Dead Souls installed. Then log in, and start reading
the administrator's guide, by typing these commands:

read index in guide
86 Where are read/write restrictions kept?

87 I need to test day/night descriptions, but I can't wait around all day.

88 How can I change the default prompt? Can I make it dynamic?

89 What is "unguarded"?

90 Is intermud communication secure?

100 What should I not do?


How do I start?

The first thing to do is follow the installation FAQ
to get Dead Souls installed. Then log in, and start reading
the administrator's guide, by typing these commands:

read index in guide
/secure/cfg/races/bear
/secure/cfg/races/wampa

Edit the wampa file to reflect what you think a
wampa is like. If you want new players to be able
to select wampa as their race, make sure the file
has this line in it:

PLAYER_RACE 1

Make especially sure to change the lines RACE and
LANGUAGE. When you're done editing, type:

addrace wampa



How do I make my friend an admin?

Use the groups menu in admintool, and select
"Modify a group". Select the ASSIST or SECURE group,
and enter the names of all the members it should have. If
I wanted to make xyzzy an assistant admin, I would
make him a creator, then I would edit the
ASSIST group and make the contents look like this:

/secure/cfg/races/bear
/secure/cfg/races/wampa

Edit the wampa file to reflect what you think a
wampa is like. If you want new players to be able
to select wampa as their race, make sure the file
has this line in it:

PLAYER_RACE 1

Make especially sure to change the lines RACE and
LANGUAGE. When you're done editing, type:

addrace wampa


For details:
help addrace


How do I make my friend an admin?

Use the groups menu in admintool, and select
"Modify a group". Select the ASSIST or SECURE group,
and enter the names of all the members it should have. If
I wanted to make xyzzy an assistant admin, I would
make him a creator, then I would edit the
ASSIST group and make the contents look like this:

I found a bug. For real. Can you please fix it?

Email me: <put my name here>@users.sourceforge.net

Please include a detailed description of the bug, and the exact
error text and commands that produced it. A log file or
screencap would be helpful.


I found a bug. For real. Can you please fix it?

Email me: <put my name here>@comcast.net

Please include a detailed description of the bug, and the exact
error text and commands that produced it. A log file or
screencap would be helpful.


The admintool menus let you pick options that aren't visible

I can't decide whether this is a feature or a bug. I'm
leaning toward "laziness".


What does locking the mud do, exactly?

When the mud is locked, only members of the authorized
groups are permitted to log in. By default, these
groups are SECURE, ASSIST, ELDER, and TEST. Anyone
who is not a member of these groups, whether they are
a creator or a player, is prevented from logging in.


The race help output is inadequate for role-playing. How do I change it?

By default, The admintool menus let you pick options that aren't visible

I can't decide whether this is a feature or a bug. I'm
leaning toward "laziness".


What does locking the mud do, exactly?

When the mud is locked, only members of the authorized
groups are permitted to log in. By default, these
groups are SECURE, ASSIST, ELDER, and TEST. Anyone
who is not a member of these groups, whether they are
a creator or a player, is prevented from logging in.

To lock the mud, use the admintool command, option a.
To add people to groups, use the admintool command, option v.


The race help output is inadequate for role-playing. How do I change it?

By default,
I need to know what features to expect in the next release so I don't
waste time duplicating effort

Visit http://dead-souls.net/RELEASE_NOTES for information on
the latest releases and what they contain. The topmost
version is usually not yet available for download, and
is listed so that folks know what's coming in the
next release. If this is so the version name will have
"(unreleased)" next to it.

As of 2.0r19, the dsversion command is available to
allow you to query that site from the mud itself.

To see what I'm working on, see http://dead-souls.net/plan.txt


I need to know what features to expect in the next release so I don't
waste time duplicating effort

Visit http://dead-souls.net/RELEASE_NOTES for information on
the latest releases and what they contain. The topmost
version is usually not yet available for download, and
is listed so that folks know what's coming in the
next release. If this is so the version name will have
"(unreleased)" next to it.

As of 2.0r19, the dsversion command is available to
allow you to query that site from the mud itself.

To see what I'm working on, see http://dead-souls.net/plan.txt


events

The following events are pending:
1145159511 RotateLogs Sun Apr 16 03:51:51 2006 EDT

eval return remove_event(
1145159511)
!
!
Where does user monitor data go?

When you monitor someone, or if you enable
GLOBAL_MONITOR, monitor data is logged into /secure/log/adm.


How would you set a race to be selectable by new players?

Edit the race file and have this line near the top:

PLAYER_RACE 1

Then use the removerace and addrace commands. For example:

removerace tauren
addrace tauren
!

Where is emote data kept? Can I edit it by hand?

Emote data is saved in /save/soul.o

You must never, ever, edit an .o file. Period. It
is possible to do it without corrupting data, but I do
not condone it, I don't recommend it, and if you fux your
mud because you did it anyway, I won't support it.

If you edit an .o file, and now things don't
work, it is your own fault. If you didn't back things up
before editing system files, there's nothing anyone can
do to retroactively save your data.


events

The following events are pending:
1145159511 RotateLogs Sun Apr 16 03:51:51 2006 EDT

eval return remove_event(
1145159511)
!
!
Where does user monitor data go?

When you monitor someone, or if you enable
GLOBAL_MONITOR, monitor data is logged into /secure/log/adm.


How would you set a race to be selectable by new players?

Edit the race file and have this line near the top:

PLAYER_RACE 1

Then use the removerace and addrace commands. For example:

removerace tauren
addrace tauren
!
For details:
help addrace


Where is emote data kept? Can I edit it by hand?

Emote data is saved in /save/soul.o

You must never, ever, edit an .o file. Period. It
is possible to do it without corrupting data, but I do
not condone it, I don't recommend it, and if you fux your
mud because you did it anyway, I won't support it.

If you edit an .o file, and now things don't
work, it is your own fault. If you didn't back things up
before editing system files, there's nothing anyone can
do to retroactively save your data.


3) Any admin on any mud has 100% access to the i3 packet data
that comes in and out, meaning they can listen to "private" tells
between someone on that mud and someone on another mud.

4) Nobody on any client mud is able to "sniff" or "snoop" data from
tells between other muds. If Alice@AlphaMud and Bob@BravoMud are
having a heated "tell" discussion, Carol@CharlieMud can't listen in,
even if she's an admin on her mud. However, Dave@DeltaMud is
the admin on the i3 router mud, and he can "hear" everything.

5) Local channels (cre, admin, newbie, etc) do not get broadcast
to the i3 router. There is one exception to this. Dead Souls 2.0r22
had a bug that did just this thing. This bug is not
seen in earlier versions, and later versions have been fixed to
prevent this. However, any local admin has full access to any
local channel.

6) Since this is all plaintext, anyone at all along the
network stream (you ISP, their ISP, etc) can listen in,
whether at the intermud point, or at the point where you
or your message target telnetted into their mud.


Therefore: do not tell secrets across intermud.


! - ! Cratylus
!
!
Dead Souls ! Homepage
!
--- 575,590 ---- style="font-weight: bold;">3) Any admin on any mud has 100% access to the i3 packet data
that comes in and out, meaning they can listen to "private" tells
between someone on that mud and someone on another mud.

4) Nobody on any client mud is able to "sniff" or "snoop" data from
tells between other muds. If Alice@AlphaMud and Bob@BravoMud are
having a heated "tell" discussion, Carol@CharlieMud can't listen in,
even if she's an admin on her mud. However, Dave@DeltaMud is
the admin on the i3 router mud, and he can "hear" everything.

5) Local channels (cre, admin, newbie, etc) do not get broadcast
to the i3 router. There is one exception to this. Dead Souls 2.0r22
had a bug that did just this thing. This bug is not
seen in earlier versions, and later versions have been fixed to
prevent this. However, any local admin has full access to any
local channel.

6) Since this is all plaintext, anyone at all along the
network stream (you ISP, their ISP, etc) can listen in,
whether at the intermud point, or at the point where you
or your message target telnetted into their mud.


Therefore: do not tell secrets across intermud.


What should I not do?

There aren't too many "don'ts", but they tend to
be important, so try to follow these guidelines:

- Don't mess with /realms/template/ unless you know exactly
what you're doing. Breaking anything there will hose up
new creators. The same goes for /secure/sefun/make_workroom.c

- Don't let just anyone off the street become Creator. You
need to know and trust your builders.

- Don't let a week go by without a full backup of your mud.


! - ! Cratylus
!
! Dead ! Souls ! Homepage
!
diff -c -r --new-file ds2.0r26/lib/www/ds-creator-faq.html ds2.0r29/lib/www/ds-creator-faq.html *** ds2.0r26/lib/www/ds-creator-faq.html Sun Jun 18 16:08:36 2006 --- ds2.0r29/lib/www/ds-creator-faq.html Fri Jul 7 19:41:43 2006 *************** *** 8,15 **** !
Dead Souls Creator FAQ, v3.0

Written by Cratylus @ Frontiers, March 2006
Updated May 2006.

Note: commands are displayed in boldface, like this: ls -a

What's this FAQ about?


There are common issues and questions that crop
up for most new creators. This document is intended to
ease or at least shorten what can be a steep learning
curve.


!
Dead Souls Creator FAQ, v3.2

Written by Cratylus @ Frontiers, March 2006
Updated July 2006.

Note: commands are displayed in boldface, like this: ls -a

What's this FAQ about?


There are common issues and questions that crop
up for most new creators. This document is intended to
ease or at least shorten what can be a steep learning
curve.


2.55 How do I make an object you can [ jump on | climb | etc ] ?

2.56 Where is the list of available skills? How do I add skills?

2.57 Where is the list of available classes? How do I add a class?


2.58 Where is the list of available races?


Section 3: Intermud and channel stuff

3.1 How do I know what other muds are online on intermud?

3.2 Hey, LeetFooMud is online! How can I tell if Biff is logged on?

2.55 How do I make an object you can [ jump on | climb | etc ] ?

2.56 Where is the list of available skills? How do I add skills?

2.57 Where is the list of available classes? How do I add a class?


2.58 Where is the list of available races?

2.59 How do languages work? Is there a list of them?

2.60 When I try to call test->SetLanguage("Bozo", 50), it sets it to 100%

2.61 How do I update an .h file?


Section 3: Intermud and channel stuff

3.1 How do I know what other muds are online on intermud?

3.2 Hey, LeetFooMud is online! How can I tell if Biff is logged on?

5.3 How do I build an area?

5.4 How do I make a quest?

5.5 Where's Leo?

5.6 Where are the vehicles and mounts?

5.7 I'm having trouble adding meals to my barkeep with QCS.

5.8 I heard DS has stargates. Where's an example?


!
!
Section 1: Getting Started


5.3 How do I build an area?

5.4 How do I make a quest?

5.5 Where's Leo?

5.6 Where are the vehicles and mounts?

5.7 I'm having trouble adding meals to my barkeep with QCS.

5.8 I heard DS has stargates. Where's an example?


5.9 I created a vendor, but he isn't responding to the "list" command.

5.10 I gave room with a default smell but I cannot get any other smells in there,

such as 'smell object' for example


!
!
Section 1: Getting Started


lines


2) Your mud is probably on the intermud3 network. If
your administrator has not restricted intermud channels,
you should be able to ask questions on the Dead Souls
intermud channel, with a command like this:

ds hi! can someone tell me what room Leo lives in?

3) If intermud is down, or nobody is answering, or
you have a bug to report, you can also try emailing
me, the author of this doc, at: <my name here>@users.sourceforge.com


4) If intermud is down, you can also log into the
Dead Souls demo mud at rugose.com 6666
This mud automatically promotes users to
creator status, allowing guests to get a feel for
what developing on Dead Souls is like.
You can try to log into that mud and see if anyone
is available to answer your question. Intermud is disabled
there, though, so you won't be able to use the ds line
to ask questions.


Important note about asking on <lines


2) Your mud is probably on the intermud3 network. If
your administrator has not restricted intermud channels,
you should be able to ask questions on the Dead Souls
intermud channel, with a command like this:

ds hi! can someone tell me what room Leo lives in?

3) If intermud is down, or nobody is answering, or
you have a bug to report, you can also try emailing
me, the author of this doc, at: <my name here>@comcast.net


4) If intermud is down, you can also log into the
Dead Souls demo mud at rugose.com 6666
This mud automatically promotes users to
creator status, allowing guests to get a feel for
what developing on Dead Souls is like.
You can try to log into that mud and see if anyone
is available to answer your question. Intermud is disabled
there, though, so you won't be able to use the ds line
to ask questions.


Important note about asking on <All I did was change one thing in a file, and now it won't update. Help!

You should make it a habit to make backup copies of files
before editing them. That way, if you screw up the code, you can
just copy the backup to the original filename.

A convenient way to do this is the bk command. See
the debugging page for an example of its use.

If you are using Windows, you need to be aware of the
linefeed problem. unix text files and DOS text files have different
formatting. If you edit files in Notepad, then try to update them,
you may find that the file no longer updates, no matter what
you do. The difference is usually invisible to you, so you can't
tell why a file that looks exactly the same as before now won't
work.

Dead Souls expects unix-formatted text, and if you feed it
something else, the results aren't likely to be to your
satisfaction. Make sure you use an editor that respects unix
text. In Windows 2000, WordPad seems to do a reasonable job of not
completely screwing things. It does, however, add carriage
returns to your lines, so when you look at them in ed, you'll
see a bunch of "^M"'s all over the place.

Take a look at the third party downloads page for
some suggestions as to what to use instead of the default
Windows editors.

If you still have trouble, take a look at the All I did was change one thing in a file, and now it won't update. Help!

You should make it a habit to make backup copies of files
before editing them. That way, if you screw up the code, you can
just copy the backup to the original filename.

A convenient way to do this is the bk command. See
the debugging page for an example of its use.

If your file is in the /tmp directory, it won't update.
The lib uses /tmp for temporary system files, and as
a result, it is a security feature that files in /tmp can't
be loaded into memory.

If you are using Windows, you need to be aware of the
linefeed problem. unix text files and DOS text files have different
formatting. If you edit files in Notepad, then try to update them,
you may find that the file no longer updates, no matter what
you do. The difference is usually invisible to you, so you can't
tell why a file that looks exactly the same as before now won't
work.

Dead Souls expects unix-formatted text, and if you feed it
something else, the results aren't likely to be to your
satisfaction. Make sure you use an editor that respects unix
text. In Windows 2000, WordPad seems to do a reasonable job of not
completely screwing things. It does, however, add carriage
returns to your lines, so when you look at them in ed, you'll
see a bunch of "^M"'s all over the place.

Take a look at the third party downloads page for
some suggestions as to what to use instead of the default
Windows editors.

If you still have trouble, take a look at the new stuff get compiled?


Dead Souls can be very strange to people used
to non-LPC muds. This is because many other kinds of
muds use a system where the mud is written in C++,
and to make changes, you need to add C++ code to the
source, recompile it, then reboot the mud.
In that kind of system, building is done with
tools where you fill in blanks and code is generated
for you. I presume that some C++ expertise is
required for doing anything unusual or fancy.

If you come from this kind of environment,
you may be in for a little disorientation. On a Dead
Souls mud, there is no need for compiling code. You
don't need to reboot the mud for new stuff to
be available.

You can add your new Orc God of War to the
game (after you code him, of course) with two
simple commands:

update /realms/<you>/area/npc/grimmash.c

clone /realms/<you>/area/npc/grimmash.c

You're now face to face with him. This makes
Dead Souls, like most LPC muds, very flexible in
what can be done, and very stable in terms of
needing few reboots. Reboots typically are
necessary only when someone breaks important
code, or to implement major mud-wide changes.

So, just write your code, and update it.
It's that simple. There are two main ways to do
this. The easiest way is with the QCS, or quick
creation system. With the QCS, you don't even need
to look at code. You just issue a few commands,
and your new whatever is there.
Check out an example
of the QCS here.


To learn the QCS, read the Creator's
Manual starting on chapter 31.

The other way to create on-line is
with the ed command. The ed editor is a powerful
and flexible way of editing files. Some people
find it difficult at first, and you might even
be able to avoid it for a while if you mostly
just use QCS. However, you'll eventually need to
know a little about ed. For a tutorial, go here.

For more detailed documentation,
type: help ed


new stuff get compiled?

Dead Souls can be very strange to people used
to non-LPC muds. This is because many other kinds of
muds use a system where the mud is written in C++,
and to make changes, you need to add C++ code to the
source, recompile it, then reboot the mud.
In that kind of system, building is done with
tools where you fill in blanks and code is generated
for you. I presume that some C++ expertise is
required for doing anything unusual or fancy.

If you come from this kind of environment,
you may be in for a little disorientation. On a Dead
Souls mud, there is no need for compiling code. You
don't need to reboot the mud for new stuff to
be available.

You can add your new Orc God of War to the
game (after you code him, of course) with two
simple commands:

update /realms/<you>/area/npc/grimmash.c

clone /realms/<you>/area/npc/grimmash.c

You're now face to face with him. This makes
Dead Souls, like most LPC muds, very flexible in
what can be done, and very stable in terms of
needing few reboots. Reboots typically are
necessary only when someone breaks important
code, or to implement major mud-wide changes.

So, just write your code, and update it.
It's that simple. There are two main ways to do
this. The easiest way is with the QCS, or quick
creation system. With the QCS, you don't even need
to look at code. You just issue a few commands,
and your new whatever is there. Check out an example
of the QCS here.


To learn the QCS, read the Creator's
Manual starting on chapter 31.

The other way to create on-line is
with the ed command. The ed editor is a powerful
and flexible way of editing files. Some people
find it difficult at first, and you might even
be able to avoid it for a while if you mostly
just use QCS. However, you'll eventually need to
know a little about ed. For a tutorial, go here.

For more detailed documentation,
type: help ed


I explored around in /domains/Ylsrim and <XYZ> is broken

Ylsrim is kept in the distribution as a kind of
sentimental artifact. It's the demo area that the
original Dead Souls shipped with, and although
it's mostly been fixed up to work with Dead Souls 2,
things can behave unexpectedly. There will be
no new fixes to Ylsrim. Please consider it a museum
exhibit that stands as-is.


I explored around in /domains/town and <XYZ> is broken

Please send me an email and let me know, so I
can fix it. Also let me know if something in /domains/default
is hosed up.


!
Section 2: Code

I explored around in /domains/Ylsrim and <XYZ> is broken

Ylsrim is kept in the distribution as a kind of
sentimental artifact. It's the demo area that the
original Dead Souls shipped with, and although
it's mostly been fixed up to work with Dead Souls 2,
things can behave unexpectedly. There will be
no new fixes to Ylsrim. Please consider it a museum
exhibit that stands as-is.


I explored around in /domains/town and <XYZ> is broken

Please send me an email and let me know, so I
can fix it. Also let me know if something in the default,
campus, or examples domain is hosed up.


!
Section 2: Code

object *stuff = filter(deep_inventory(this_player()), (: inherits(LIB_ARMOR,$1) :) );
string *mystuff = filter(stuff, (: base_name($1)+".c" :) );

using foreach:

string *mystuff = ({});
foreach( object ob in deep_inventory(this_player())){
if( inherits(LIB_ARMOR, ob) ) mystuff += ({ base_name(ob)+".c" });
}

There are arguments favoring the use of either. I won't get into
it. As far as I can tell, it's really a question of preference.
You can structure these functions more elegantly
than shown here, to best suit you. But this is the idea.


object *stuff = filter(deep_inventory(this_player()), (: inherits(LIB_ARMOR,$1) :) );
string *mystuff = filter(stuff, (: base_name($1)+".c" :) );

using foreach:

string *mystuff = ({});
foreach( object ob in deep_inventory(this_player())){
if( inherits(LIB_ARMOR, ob) ) mystuff += ({ base_name(ob)+".c" });
}

There are arguments favoring the use of either. I won't get into
it. As far as I can tell, it's really a question of preference.
You can structure these functions more elegantly
than shown here, to best suit you. But this is the idea.


member_array( "foo", ({ "foo", "bar", "baz" }) ) returns: 0

Why does it return 0? Because "foo" is element 0 of the
array. If this_array == ({ "foo", "bar", "baz" }), then
this_array[0] is "foo". So member_array("foo", this_array)
would return 0.

If the first argument is not a member of the array, member
array returns -1. So that:

member_array( "shiz", ({ "foo", "bar", "baz" }) ) returns: -1


Example:

Does this player know how to polka? Return 1 for yes:

RIGHT: if(member_array("polka dancing", this_player()->GetSkills()) != -1) return 1;

WRONG: if(member_array("polka dancing", this_player()->GetSkills()) ) return 1;
 
The first way says "If 'polka dancing' has an element number that isn't -1,
then it is a member, so let's return 1"

The second way says "If 'polka dancing' has an element number that isn't 0,
then it is a member, so let's return 1"

The problem with the second way is that it is possible for "polka dancing"
to be element 0 in that array, and if it is, your code will incorrectly
tell you that you can't polka dance. But worse than this is that if
you actually can't polka dance, this second way will incorrectly tell
you that you can. Given random input, the second way would be wrong more than
half the time.


I'm trying to add two mappings together and the results are bizarre

Adding mappings together has to be done just so in order for
it to work the way one might expect. What can happen in
mapping arithmetic is that in the process of trying to
add the values of one mapping to another, you can change the
values of a mapping you didn't intend to. The deal is a
conflict between passing data by reference or by value. To
be sure that you don't accidentally modify an innocent
bystander, use the add_maps() sefun. For example:

MyMap = add_maps(HisMap, HerMap);

or

MyMap = add_maps(MyMap, HerMap);


member_array( "foo", ({ "foo", "bar", "baz" }) ) returns: 0

Why does it return 0? Because "foo" is element 0 of the
array. If this_array == ({ "foo", "bar", "baz" }), then
this_array[0] is "foo". So member_array("foo", this_array)
would return 0.

If the first argument is not a member of the array, member
array returns -1. So that:

member_array( "shiz", ({ "foo", "bar", "baz" }) ) returns: -1


Example:

Does this player know how to polka? Return 1 for yes:

RIGHT: if(member_array("polka dancing", this_player()->GetSkills()) != -1) return 1;

WRONG: if(member_array("polka dancing", this_player()->GetSkills()) ) return 1;
 
The first way says "If 'polka dancing' has an element number that isn't -1,
then it is a member, so let's return 1"

The second way says "If 'polka dancing' has an element number that isn't 0,
then it is a member, so let's return 1"

The problem with the second way is that it is possible for "polka dancing"
to be element 0 in that array, and if it is, your code will incorrectly
tell you that you can't polka dance. But worse than this is that if
you actually can't polka dance, this second way will incorrectly tell
you that you can. Given random input, the second way would be wrong more than
half the time.


I'm trying to add two mappings together and the results are bizarre

Adding mappings together has to be done just so in order for
it to work the way one might expect. What can happen in
mapping arithmetic is that in the process of trying to
add the values of one mapping to another, you can change the
values of a mapping you didn't intend to. The deal is a
conflict between passing data by reference or by value. To
be sure that you don't accidentally modify an innocent
bystander, use the add_maps() sefun. For example:

MyMap = add_maps(HisMap, HerMap);

or

MyMap = add_maps(MyMap, HerMap);


My NPC's stats are all hosed up.

Make sure you have SetLevel() *after* SetRace() and SetClass().
Also make sure there's a working ::create() in your create
function. Some examples are:

::create();
npc::create();
vendor::create();

And make sure your init() function has an:

::init();


This squirrel is taking *forever* to kill.

The mud is calculating its health points based on level and
race. If your squirrel has 340hp, it'll seem unreasonably
tough. Use SetMaxHealthPoints() to cap its vitality.


My room should not be entered/exited by just anyone. How
My NPC's stats are all hosed up.

Make sure you have SetLevel() *after* SetRace() and SetClass().
Also make sure there's a working ::create() in your create
function. Some examples are:

::create();
npc::create();
vendor::create();

And make sure your init() function has an:

::init();


This squirrel is taking *forever* to kill.

The mud is calculating its health points based on level and
race. If your squirrel has 340hp, it'll seem unreasonably
tough. Use SetMaxHealthPoints() to cap its vitality to
something like, say, 5.


My room should not be entered/exited by just anyone. How
man sscanf

If you're looking for lists of library functions,
such as SetClass in LIB_WEAPON, your best bet is the help
command, like this:

help library objects weapon

help library objects creator

That will list the functions in the library object
you specify. As of this writing, the documentation on lfuns
is not yet as thorough as the documentation on efuns and sefuns,
but this documentation is an ongoing project whose output
should eventually improve.


How do I make an object you can [ jump on | climb | etc ] ?

Look for an example, and copy it. Take a look at the
code in the newbie mansion ladder for climb code. Take a look
at /domains/Ylsrim/room/bank_roof.c for an example of something
you can jump from. Other actions will have similar examples. The
sample domains are there for you to explore and find examples
of what you want to do.


man sscanf

If you're looking for lists of library functions,
such as SetClass in LIB_WEAPON, your best bet is the help
command, like this:

help library objects weapon

help library objects creator

That will list the functions in the library object
you specify. As of this writing, the documentation on lfuns
is not yet as thorough as the documentation on efuns and sefuns,
but this documentation is an ongoing project whose output
should eventually improve.

A contributor to the mud community has made
available a wikified cross-reference of Dead Souls funs,
which you can find here:

http://lpuni.org/components/com_mambowiki/index.php/DeadSouls_Reference


How do I make an object you can [ jump on | climb | etc ] ?

Look for an example, and copy it. Take a look at the
code in the newbie mansion ladder for climb code. Take a look
at /domains/Ylsrim/room/bank_roof.c for an example of something
you can jump from. Other actions will have similar examples. The
sample domains are there for you to explore and find examples
of what you want to do.


Where is the list of available races?

Type: ls /secure/cfg/races

For details on adding races, see the admin FAQ.


!
!
Section 3: Intermud and channel stuff


Where is the list of available races?

Type: ls /secure/cfg/races

For details on adding races, see the admin FAQ.


How do languages work? Is there a list of them?

There is no list of languages. It doesn't work that way.
There is no centralized language database, daemon, or anything
like that. Languages are basically like a skill: only useful to
the extent that lib objects make use of them.

A player might be able to understand Tamarian, but if
nobody else in the lib does, it isn't much use. If no written material
is in Tamarian besides, then the player's language ability is a waste.

On the other hand, if a player wants to be able to
understand orcs, all she has to do is find a language teacher
that can instruct her in that tongue. After enough lessons,
she will be at 100% fluency, and if she encounters written or
spoken information in Tangetto, she'll be able to understand
all of it.

To know what languages you understand, and to what
extent, use the command:

language

To make yourself fluent in English, type:

anglicize me

To make yourself fluent in all languages, type:

polyglottize me

Obviously these commands are available only to creators.


When I try to call Bozo->SetLanguage("Clownish", 50), it sets it to 100%

Bozo is probably a newbie. If Bozo's player level is at or below
what is defined as newbie in /secure/include/config.h, then he understands
all languages at 100%. Raise his level above that, and you should see
his proficiency in that language drop to what you specified.


How do I update an .h file?

You don't, really. That's a header file, which contains code to
be included by a .c file. Only a .c file gets loaded into memory, so
to "update" an .h file, you update the .c file that includes it. In
the case of a global include, like daemons.h, you would update the
master object (also called the master daemon) thusly:

update /secure/daemon/master


!
!
Section 3: Intermud and channel stuff


This guy keeps hassling me on an intermud channel

Sometimes people just can't leave well enough alone,
and they spam. Some people just don't have anything
to say that you want to hear. For such situation,
use the earmuff command. For example:

earmuff tatianna

And you will not receive channel messages from
that person. The reverse command is unmuff.
Earmuffing is also good when someone from
a non-European-language mud sends well-meaning
but garbled, escape-code filled gibberish. If
she doesn't understand your English language
requests to stop spamming, you can just earmuff her.

!
Section ! 4: Miscellanea
!
!
I'm fighting the beggar with my staff and he's kicking my ass
!
!     ! For one thing, you're a creator. Quit goofing around. If
! you want to ! fight monsters and stuff, create a test
! player ! character.
!
!     ! Next, you're probably still a Level 1 character. This
! makes you a ! wimp. Raise your level with this command:
!
! call ! me->SetLevel(20)
!
!     ! Now get the medical tricorder from your workroom's
! chest and ! raise your stats. Give yourself 100 strength.
! Why not?

    If you're carrying a chest, table, chair, and everything
--- 560,593 ---- style="font-weight: bold;">This guy keeps hassling me on an intermud channel


Sometimes people just can't leave well enough alone,
and they spam. Some people just don't have anything
to say that you want to hear. For such situation,
use the earmuff command. For example:

earmuff tatianna

And you will not receive channel messages from
that person. The reverse command is unmuff.
Earmuffing is also good when someone from
a non-European-language mud sends well-meaning
but garbled, escape-code filled gibberish. If
she doesn't understand your English language
requests to stop spamming, you can just earmuff her.

!
Section ! 4: Miscellanea
!
!
I'm fighting the beggar with my staff and he's kicking my ass
!
!     ! For one thing, you're a creator. Quit goofing around. If
! you want to ! fight monsters and stuff, create a test
! player ! character.
!
!     ! Next, you're probably still a Level 1 character. This
! makes you a ! wimp. Raise your level with this command:
!
! call ! me->SetLevel(20)
!
!     ! Now get the medical tricorder from your workroom's
! chest and ! raise your stats. Give yourself 100 strength.
! Why not?

    If you're carrying a chest, table, chair, and everything
*************** *** 593,776 **** shopping bags and boxes, and see how well you do against
a pissed off real-life enemy. You won't last long. So either
drop all the crap you're lugging around, or put it in
! a backpack and wear the pack.
!
!     ! Put the staff in your robe and quit using it as
! a weapon. ! It's a creating tool. Not only is it a
! poor weapon, ! by default you lack double-handed
! weapon ! skills, making you really crappy at using
! a really ! crappy weapon. No wonder the orcs were
! beating you ! like an animal. Get a carving knife
! from the ! mansion. Or an orcslayer. Or hell, just
! use the zap ! command and stop wasting time. You
! should have ! characters for this.
!
!
!
!
Someone amputated all my limbs and I can't do anything!
!
! If your body ! gets damaged you can restore yourself to your
! normal ! physical status by typing:
!
! heal me

!
How do I change my class?
!
!
Again with the pretending to be a ! player. Seriously,
! you need a ! test player char so that if you screw something
! up, you don't ! screw *yourself* up.
!
! But, if ! you're determined:

call me->ChangeClass("thief")

!
Your ! stats and levels will probably be all weird and
! hosed up. ! Just raise your player level, that will probably
! fix it.
!

!
!
!
People are talking to me in gibberish, even though it 
says they're
speaking English.

!
! If your race is not human, your default language is not English, ! therefore
! someone ! speaking in English would not be understood by you. As a
! creator, you ! can avoid players' tedious language learning process
! and simply ! type:
!
! call ! me->SetLanguage("English",100)
!
!     ! Obviously this will work for other languages too.
!
!
!
!
! What's ! this about Biff "unknowingly" telling me something?
!
! If you are ! invis and a player or someone on another mud tells
! to you, they ! get an error message about you not being around. So,
! they told to ! you, but do not know you actually got the message,
! since you ! don't seem logged on.
!
!
!
!
How do I find the location of a verb or command?
!
! Use the which ! command. For example:
!
! which ! zap
!
! which ! update
!
! If 'which' ! doesn't find it, the command is probably built into
! some object ! you inherit, like the command shell or the
! hooks for the ! chat daemon. Or it may be an add_action bound to a
! nearby ! object. To see what commands objects or inherited
! files might ! be providing you, type:
!
! localcmds
!
!
!
!
 Where are the "exa" and "n" commands?

When you type some commands, like exa, n, or i,
what happens is that your command shell recognizes
them as aliases, and turns the alias into the appropriate
command.
An alias is like a nickname, or shorter word,
for a command or series of commands. To see the aliases
you currently have, type:
a pissed off real-life enemy. You won't last long. So either
drop all the crap you're lugging around, or put it in
! a backpack and wear the pack.
!
!     ! Put the staff in your robe and quit using it as
! a weapon. ! It's a creating tool. Not only is it a
! poor weapon, ! by default you lack double-handed
! weapon ! skills, making you really crappy at using
! a really ! crappy weapon. No wonder the orcs were
! beating you ! like an animal. Get a carving knife
! from the ! mansion. Or an orcslayer. Or hell, just
! use the zap ! command and stop wasting time. You
! should have ! characters for this.
!
!
!
!
Someone amputated all my limbs and I can't do anything!
!
! If your body ! gets damaged you can restore yourself to your
! normal ! physical status by typing:
!
! heal me

!
How do I change my class?
!
!
Again with the pretending to be a ! player. Seriously,
! you need a ! test player char so that if you screw something
! up, you don't ! screw *yourself* up.
!
! But, if ! you're determined:

call me->ChangeClass("thief")

!
Your ! stats and levels will probably be all weird and
! hosed up. ! Just raise your player level, that will probably
! fix it.
!

!
!
!
People are talking to me in gibberish, even though it 
says they're
speaking English.

!
! If your race is not human, your default language is not English, ! therefore
! someone ! speaking in English would not be understood by you. As a
! creator, you ! can avoid players' tedious language learning process
! and simply ! type:
!
! call ! me->SetLanguage("English",100)
!
!     ! Obviously this will work for other languages too.
!
!
!
!
! What's ! this about Biff "unknowingly" telling me something?
!
! If you are ! invis and a player or someone on another mud tells
! to you, they ! get an error message about you not being around. So,
! they told to ! you, but do not know you actually got the message,
! since you ! don't seem logged on.
!
!
!
!
How do I find the location of a verb or command?
!
! Use the which ! command. For example:
!
! which ! zap
!
! which ! update
!
! If 'which' ! doesn't find it, the command is probably built into
! some object ! you inherit, like the command shell or the
! hooks for the ! chat daemon. Or it may be an add_action bound to a
! nearby ! object. To see what commands objects or inherited
! files might ! be providing you, type:
!
! localcmds
!
!
!
!
 Where are the "exa" and "n" commands?

When you type some commands, like exa, n, or i,
what happens is that your command shell recognizes
them as aliases, and turns the alias into the appropriate
command.
An alias is like a nickname, or shorter word,
for a command or series of commands. To see the aliases
you currently have, type:
alias ig

After modifying aliases, make sure to type:
save 
!     !
!
 How do I get something to happen to a random person in a room?
! You can pick a random winner (or victim) for your action by using the ! get_random_living()
! sefun. For ! details on its usage:
!
! man ! get_random_living
!
! You may also ! find the get_livings() sefun useful.
!
!
!
My wandering monster escaped from my workroom! How can
I find him?

If its name is jabberwock, try:

findobj jabberwock

You can also probably just:

goto jabberwock
!
!
!
I ran findobj on something but it says no environment. Where is it?
!
! Right where ! it says. Some objects create a "master copy" of themselves
! when they are ! cloned. This copy remains loaded in memory even if
! that cloned ! object goes away. You can distinguish between cloned
! objects and ! master copies by the number sign  and number at the end
! of cloned ! objects. The master copy has no instance number. It is
! simply loaded ! code, and does not "exist" in a way accessible to your player
! object on the ! mud.
!
! Sometimes a ! cloned object will lose its environment. This is usually
! caused by an ! error and is not a good thing. Dead Souls runs a
! "reaper" ! daemon that periodically searches memory for cloned
! objects that ! lack an environment, and they are destroyed.
!
!
!
!
How do I update everything in a directory?
!
! You really ! shouldn't. There are very few cases I can think
! of where ! updating an entire directory is something an average
! creator needs ! to do. How often do you edit multiple
! files at once ! without individually updating them? Good
! coding ! practice is to update the one file you just worked on to know
! if it works ! at all.
!
! I also ! discourage it because when you do this, you lag the mud
! considerably. ! I/O is the most resource intensive kind of operation,
! and updating ! is on its own quite resource intensive. Updating a
! directory ! with dozens of files in it will cause a noticeable hiccup
! in the rest ! of the mud.
!
! If you are determined to do this, though, the ! command is :
!
! update ! /path/to/dir/*
!
!
!
!
I don't like getting colors on my screen. How do I stop it?
!
! Type: terminal ! unknown
!
! then type: save
!
!
!
!
Um...I want colors back now please
!
! Type: terminal ! ansi
!
! then type: save
!
!
!
!
 I can type 'n' and move north, but 'north' doesn't work.
!
! Technically, ! you can't 'n' either. When you type 'n', what
! it happening ! is that your preset alias turns that 'n'
! into the ! command line 'go ! north'.
!     ! Because you do not have an alias 'north' that expands
! to 'go ! north', 'north' doesn't ! take you anywhere. But
! go ! north ! will.
!
!
!
!
 Why is there a bunch of stuff in ROOMS_FURNACE?
!
! The QCS is ! designed to attempt the graceful handling
! of unusual ! events. Sloppy code, non-working objects,
! etc. Part of ! this design is avoiding a situation
! where an ! object's destruction affects your local
! environment ! (and this happens a bit more often than
! you might ! think).
!     ! To avoid some types of unpleasantness, QCS doesn't
! try to ! immediately destruct objects when replacing them.
! Instead, they ! are moved, along with whatever problems
! they might ! have, to ROOMS_FURNACE. That is a room
! where things ! go to be destructed quietly. Every
! second or so, ! the contents of that room are destroyed,
! and their ! bits recycled.
!     ! A few other items in the lib use the furnace,
! notably the ! recycling bins and the reload command.
!
!
! How do I change ! my screen and terminal settings?
!
! help ! terminal
!
! help ! screen
!
! screen ! 79 24
!
!
!
 ZOMG this is the best mudlib evar how can I evar thank you?
!
! No need, ! citizen. Merely doing my job.
!
! Just let me ! know what bugs you find, and how I can
! make the lib ! better.
!
!
Dude this mudlib sux0rz @ss. What a waste of my time.

I'm sure Dead Souls has lots of things that you don't
like, but I can't fix them if I don't know what they are.
Email me so that I can understand the lameness, and so
others can benefit for your suggestions.


I'm seeing a filename but I can't read it.

If you try command and you get something like:

/secure/foo/bar: No such reference.

It means you don't have read access to that
file or directory. I've someone make a stink about
how a file they can't read shouldn't be visible to them
or some such thing. However, I think he was just
being difficult. Some files you can't read, even
though you have access to the directory they're in.
That's the story.


alias ig

After modifying aliases, make sure to type:
save 
!     !
!
 How do I get something to happen to a random person in a room?
! You can ! pick a random winner (or victim) for your action by using the ! get_random_living()
! sefun. For ! details on its usage:
!
! man ! get_random_living
!
! You may also ! find the get_livings() sefun useful.
!
!
!
My wandering monster escaped from my workroom! How can
I find him?

If its name is jabberwock, try:

findobj jabberwock

You can also probably just:

goto jabberwock
!
!
!
I ran findobj on something but it says no environment. Where is it?
!
! Right where ! it says. Some objects create a "master copy" of themselves
! when they are ! cloned. This copy remains loaded in memory even if
! that cloned ! object goes away. You can distinguish between cloned
! objects and ! master copies by the number sign  and number at the end
! of cloned ! objects. The master copy has no instance number. It is
! simply loaded ! code, and does not "exist" in a way accessible to your player
! object on the ! mud.
!
! Sometimes a ! cloned object will lose its environment. This is usually
! caused by an ! error and is not a good thing. Dead Souls runs a
! "reaper" ! daemon that periodically searches memory for cloned
! objects that ! lack an environment, and they are destroyed.
!
!
!
!
How do I update everything in a directory?
!
! You really ! shouldn't. There are very few cases I can think
! of where ! updating an entire directory is something an average
! creator needs ! to do. How often do you edit multiple
! files at once ! without individually updating them? Good
! coding ! practice is to update the one file you just worked on to know
! if it works ! at all.
!
! I also ! discourage it because when you do this, you lag the mud
! considerably. ! I/O is the most resource intensive kind of operation,
! and updating ! is on its own quite resource intensive. Updating a
! directory ! with dozens of files in it will cause a noticeable hiccup
! in the rest ! of the mud.
!
! If you are determined to do this, though, the ! command is :
!
! update ! /path/to/dir/*
!
!
!
!
I don't like getting colors on my screen. How do I stop it?
!
! Type: terminal ! unknown
!
! then type: save
!
!
!
!
Um...I want colors back now please
!
! Type: terminal ! ansi
!
! then type: save
!
!
!
!
 I can type 'n' and move north, but 'north' doesn't work.
!
! Technically, ! you can't 'n' either. When you type 'n', what
! it happening ! is that your preset alias turns that 'n'
! into the ! command line 'go ! north'.
!     ! Because you do not have an alias 'north' that expands
! to 'go ! north', 'north' doesn't ! take you anywhere. But
! go ! north ! will.
!
!
!
!
 Why is there a bunch of stuff in ROOMS_FURNACE?
!
! The QCS is ! designed to attempt the graceful handling
! of unusual ! events. Sloppy code, non-working objects,
! etc. Part of ! this design is avoiding a situation
! where an ! object's destruction affects your local
! environment ! (and this happens a bit more often than
! you might ! think).
!     ! To avoid some types of unpleasantness, QCS doesn't
! try to ! immediately destruct objects when replacing them.
! Instead, they ! are moved, along with whatever problems
! they might ! have, to ROOMS_FURNACE. That is a room
! where things ! go to be destructed quietly. Every
! second or so, ! the contents of that room are destroyed,
! and their ! bits recycled.
!     ! A few other items in the lib use the furnace,
! notably the ! recycling bins and the reload command.
!
!
! How do I change ! my screen and terminal settings?
!
! help ! terminal
!
! help ! screen
!
! screen ! 79 24
!
!
!
 ZOMG this is the best mudlib evar how can I evar thank you?
!
! No need, ! citizen. Merely doing my job.
!
! Just let me ! know what bugs you find, and how I can
! make the lib ! better.
!
!
Dude this mudlib sux0rz @ss. What a waste of my time.

I'm sure Dead Souls has lots of things that you don't
like, but I can't fix them if I don't know what they are.
Email me so that I can understand the lameness, and so
others can benefit for your suggestions.


I'm seeing a filename but I can't read it.

If you try command and you get something like:

/secure/foo/bar: No such reference.

It means you don't have read access to that
file or directory. I've someone make a stink about
how a file they can't read shouldn't be visible to them
or some such thing. However, I think he was just
being difficult. Some files you can't read, even
though you have access to the directory they're in.
That's the story.


cd ^

To go to /domains/default: cd ^default

To go to the directory you were in before the current one: cd ~-


!

! Section ! 5: Building
!
!
QCS is putting stuff where I don't want it.

QCS is a way to use simple commands to manipulate
complex files. Sometimes the conversion between simple
and complex causes unusual compromises and outcomes.

When you create a new room, what QCS does
is look at the room you're currently in. Let's say
you're standing in /realms/you/area/room/test1.c. And
you issue the command

create room east test2

In this case, "test2" is considered a "relative path",
which means that you didn't provide QCS with *exactly* where
you want the file to be. You told QCS to figure out where
to put that file.
When QCS has to guess where a new room goes,
it simply assumes that the room goes in the same directory
as the current room. So, in this case, you're going to
make a file with this path:

/realms/you/area/room/test2.c

Suppose that this is not where you want the new
room to be. you want it to go into /realms/you/testrooms/.
In this case, you need to tell QCS the "full path", like this:

create room east /realms/you/testrooms/test2

When you create non-room objects, also known as
tangible items, QCS guesses in a slightly different way.
If you provide a relative name, then QCS looks at your
current working directory (cwd). Based on the type of item,
QCS looks for a directory with the appropriate name. For
example, if your cwd is /realms/you/foo, and the type of
object is a weapon, then QCS looks for a directory named
"/realms/you/foo/weap/". If it exists, it puts your new
file there. Otherwise it tries to put it in "/realms/you/weap/".
And if that doesn't work, it'll default to your home area
weapon directory, which is "/realms/you/area/weap/".

If you've been granted domain admin status, and
you are using QCS to work on your new domain, it's therefore
very important that your cwd be in the right place in the
domain directory for it to work. Otherwise, your new stuff may
wind up in your default area dir, and you could go nuts
trying to find it.

Of course, you can avoid all ambiguity by simply
using a full path, like:

create weapon /domains/My_Spiffy_Domain/weap/fruitcake

 
How do I make a blank room, instead of copying the current one?
!     You'll always copy the old room, that's just how
QCS works. But you can quickly change it to a blank
room by entering the new room and issuing this command:
--- 943,962 ---- style="font-weight: bold;">cd ^


To go to /domains/default: cd ^default

To go to the directory you were in before the current one: cd ~-


!

! Section ! 5: Building
!
!
QCS is putting stuff where I don't want it.

QCS is a way to use simple commands to manipulate
complex files. Sometimes the conversion between simple
and complex causes unusual compromises and outcomes.

When you create a new room, what QCS does
is look at the room you're currently in. Let's say
you're standing in /realms/you/area/room/test1.c. And
you issue the command

create room east test2

In this case, "test2" is considered a "relative path",
which means that you didn't provide QCS with *exactly* where
you want the file to be. You told QCS to figure out where
to put that file.
When QCS has to guess where a new room goes,
it simply assumes that the room goes in the same directory
as the current room. So, in this case, you're going to
make a file with this path:

/realms/you/area/room/test2.c

Suppose that this is not where you want the new
room to be. you want it to go into /realms/you/testrooms/.
In this case, you need to tell QCS the "full path", like this:

create room east /realms/you/testrooms/test2

When you create non-room objects, also known as
tangible items, QCS guesses in a slightly different way.
If you provide a relative name, then QCS looks at your
current working directory (cwd). Based on the type of item,
QCS looks for a directory with the appropriate name. For
example, if your cwd is /realms/you/foo, and the type of
object is a weapon, then QCS looks for a directory named
"/realms/you/foo/weap/". If it exists, it puts your new
file there. Otherwise it tries to put it in "/realms/you/weap/".
And if that doesn't work, it'll default to your home area
weapon directory, which is "/realms/you/area/weap/".

If you've been granted domain admin status, and
you are using QCS to work on your new domain, it's therefore
very important that your cwd be in the right place in the
domain directory for it to work. Otherwise, your new stuff may
wind up in your default area dir, and you could go nuts
trying to find it.

Of course, you can avoid all ambiguity by simply
using a full path, like:

create weapon /domains/My_Spiffy_Domain/weap/fruitcake

 
How do I make a blank room, instead of copying the current one?
!     You'll always copy the old room, that's just how
QCS works. But you can quickly change it to a blank
room by entering the new room and issuing this command:
*************** *** 1133,1154 **** immersive, and worth playing in. That's up
to you...I can't help you with that.

!
!
How do I make a quest?
  
Think of a quest in terms of the result.
The result of a quest is a player receiving quest
points and a quest title.
   
This means that pretty much anything can
be a quest. If you've coded a rock to provide
quest points and a quest title when it is
picked up, well, there's your Rock Quest. However,
you usually want to make things a bit more challenging.

A quest can be as boring as "pick up the red rock"
or it can be a challenging metaphysical inquiry into the
nature of consciousness. If quest points and a quest title are
at the end of a series of actions, then that series of actions
is a quest. What those actions should be are entirely up
to your imagination. Review the orcslayer quest in the
Player's Handbook for an example. You did read the
Player's Handbook, right?
  
Take a look at Leo the Archwizard's code for an example of the
mechanics of solving a quest.
! Where's ! Leo?
!
! Read the ! Player's Handbook already, please.
!


!
Where are the vehicles and mounts?

There are none yet. After 2.1 is released, I'll
be able to concentrate on adding new systems like that.
For now, it's just bugfixes and vital functionality
I'm working on. However, 2.1 should be released
Real Soon Now.


I'm having trouble adding meals to my barkeep with QCS.

Cratylus <ds> ok here's the deal

to you...I can't help you with that.

!
!
How do I make a quest?
  
Think of a quest in terms of the result.
The result of a quest is a player receiving quest
points and a quest title.
   
This means that pretty much anything can
be a quest. If you've coded a rock to provide
quest points and a quest title when it is
picked up, well, there's your Rock Quest. However,
you usually want to make things a bit more challenging.

A quest can be as boring as "pick up the red rock"
or it can be a challenging metaphysical inquiry into the
nature of consciousness. If quest points and a quest title are
at the end of a series of actions, then that series of actions
is a quest. What those actions should be are entirely up
to your imagination. Review the orcslayer quest in the
Player's Handbook for an example. You did read the
Player's Handbook, right?
  
Take a look at Leo the Archwizard's code for an example of the
mechanics of solving a quest.
! Where's ! Leo?

! Read the ! Player's Handbook already, please.
!

!
!
Where are the vehicles and mounts?

There are none yet. After 2.1 is released, I'll
be able to concentrate on adding new systems like that.
For now, it's just bugfixes and vital functionality
I'm working on. However, 2.1 should be released
Real Soon Now.


I'm having trouble adding meals to my barkeep with QCS.

Cratylus <ds> ok here's the deal

I heard DS has stargates. Where's an example?

The following rooms have stargates:

/domains/Ylsrim/room/tower.c

/domains/default/room/stargate_lab.c

For info on valid gates, type: stargate
!
!
! - Cratylus

! <my name here>@users.sourceforge.net
!

! Dead ! Souls Homepage
!

--- 1020,1059 ---- name="5.8">I heard DS has stargates. Where's an example?

The following rooms have stargates:

/domains/Ylsrim/room/tower.c

/domains/default/room/stargate_lab.c

For info on valid gates, type: stargate
!
!
I created a vendor, but he isn't responding to the "list" command.

The list command isn't part of the vendor object. It's
part of LIB_SHOP, which is a room that acts as a sort of front-end
for the vendor. The commands list, show, price, and appraise are
not in the vendor, but in the shop. To get the appropriate responses
from the vendor, you would use the following syntax:

list: ask vendor to browse
show: ask vendor to show <item>
price: ask vendor to price <item>
appraise: ask vendor to appraise <item>

! I ! gave room with a default smell but I cannot get any other smells in ! there,
! such as 'smell object' for example

!
!     SetSmell, like ! SetListen, is in the form of a mapping. When using the
! QCS, the correct formatting is automatically made for you. If coding
! by hand, take a look at /domains/town/room/riverbank.c for what it
! looks like. Note that for each Smell or Listen, you need a corresponding
! SetItems element.
!

!
! - Cratylus

! <my name here>@comcast.net

+ Dead + Souls Homepage
+
+
diff -c -r --new-file ds2.0r26/lib/www/ds-faq.html ds2.0r29/lib/www/ds-faq.html *** ds2.0r26/lib/www/ds-faq.html Sun Jun 18 16:08:37 2006 --- ds2.0r29/lib/www/ds-faq.html Wed Jul 5 00:00:59 2006 *************** *** 67,73 **** style="font-weight: bold; text-decoration: underline;">
How do I get started?

Download the latest version from http://dead-souls.sourceforge.net/
and install it.
There is only one distribution file, which includes both the
Windows and UNIX versions. Read the installation FAQ for details.

Once you log in, read the Players Handbook and the Creators Manual.


How do I get started?

Download the latest version from http://dead-souls.net/
and install it.
There is only one distribution file, which includes both the
Windows and UNIX versions. Read the installation FAQ for details.

Once you log in, read the Players Handbook and the Creators Manual.


Anything else?

Read the Dead Souls Admin FAQ.

Read the Dead Souls Creator's FAQ.

Read the Dead Souls Installation FAQ.

Read the Quick Creation System Example Page.

Read the
Anything else?

Read the Dead Souls Admin FAQ.

Read the Dead Souls Creator's FAQ.

Read the Dead Souls Installation FAQ.

Read the Quick Creation System Example Page.

Read the

Dead Souls - Installation FAQ

By Cratylus @ Frontiers, February 2006. Updated ! June 2006.

--- 17,23 ---- *************** *** 73,80 ****

Download the latest version from the following:

Why is there only one version? Where are the UNIX and Windows --- 73,82 ----

Download the latest version from the following:

Why is there only one version? Where are the UNIX and Windows *************** *** 100,107 ****


Should I apply the available patches during an install?

Should I apply the available patches during an install? (Back to Top)

  • first, stop using Fedora. Ha ha just kidding.
  • A recent fix may be available. Check the HOTFIX PAGE for late-breaking fixes.
  • Download only from the sites mentioned above. Those are the only ! ones sure to have the latest version. Other sites can be out of date.
  • Most of the problems with unix installs involve permissions conflicts. If you uncompress the package as root user, for example, then try to run --- 272,288 ---- class="backtotop" href="#top">(Back to Top)
    • first, stop using Fedora. Ha ha just kidding.
    • +
    • Your compiler may be trying to run a distributed "make" by + default. That's a no-go for MudOS. Try disabling that at compile time + by using this instead of the normal make command line:
      + make -j 1
      + make install
      +
    • A recent fix may be available. Check the HOTFIX PAGE for late-breaking fixes.
    • Download only from the sites mentioned above. Those are the only ! ones sure to have the latest version. Other sites can be out of date.
    • Most of the problems with unix installs involve permissions conflicts. If you uncompress the package as root user, for example, then try to run *************** *** 321,338 **** like "alpha.bravo". If your machine is under the impression that its name is localhost.localdomain, it will supply that name to mudos, which will eventually choke on it.
      -
      If you're good at C, you can edit lines 66 and 76 of v22.2b14/swap.c and correct this behavior. But the common sense fix is to stop being a noob and give your computer a proper hostname already.
    • Some hosting services may provide you unix shells so tightly ! restricted that you cannot successfully compile the mudos driver. ! Specifically, I have asked Wolfpaw for their assistance in this, but as ! of 2 days since emailing the request, have received no response. You may need to submit a problem ticket with your hosting service to resolve the issue. Let them know that the source compiles fine on various versions of SuSE and Fedora, as well as Solaris 8, 9, and 10, ! various BSD's, and even IRIX.

    --- 329,354 ---- like "alpha.bravo". If your machine is under the impression that its name is localhost.localdomain, it will supply that name to mudos, which will eventually choke on it.
    If you're good at C, you can edit lines 66 and 76 of v22.2b14/swap.c and correct this behavior. But the common sense fix is to stop being a noob and give your computer a proper hostname already.
  • Some hosting services may provide you unix shells so tightly ! restricted that you cannot successfully compile the mudos driver. You may need to submit a problem ticket with your hosting service to resolve the issue. Let them know that the source compiles fine on various versions of SuSE and Fedora, as well as Solaris 8, 9, and 10, ! various BSD's, and even IRIX (!). If you can get them to give me a free ! temporary account for testing purposes, I'll take a look and see if I ! can help.
  • !
  • If you've tried everything but the compile keeps breaking, try ! compiling as root (obviously a last resort, and just for testing).
  • !
  • If the problem is that it compiles, but when you run the driver ! no sefuns load and the driver segfaults, it is possible that you ! compiled on a 64-bit x86 box. It seems that MudOS compiled on 64-bit ! x86 Linux doesn't work right. A fix is in the works, but until it is ! available, you can do one of two things: boot into 32-bit mode and then ! compile, or compile it on a 32-bit box and move it to the 64-bit box.
    !

diff -c -r --new-file ds2.0r26/lib/www/example.html ds2.0r29/lib/www/example.html *** ds2.0r26/lib/www/example.html Sun Jun 18 16:08:42 2006 --- ds2.0r29/lib/www/example.html Wed Jul 5 00:00:59 2006 *************** *** 1,1166 **** ! ! ! ! Dead Souls Mudlib - Quick Creation System ! ! ! ! ! ! ! ! ! ! ! ! !

Index

! ! !

QCS Described

!

The Quick Creation System (or QCS) is a series of commands and modules that ! lets you create rooms, objects, exits, and NPCs easily and quickly. Before the ! QCS, if you wanted to make an orc, you would edit the text file by hand, or ! copy a template file and use an editor to manually change the lines you needed ! to modify. This could be a tiresome process, as the standard editor can be a bit ! awkward, and making dozens of objects this way could be real torture for ! beginners.

!

The QCS changes all of that. Rather than use an editor to modify files, the ! QCS gives you commands that permit you to modify objects on the fly. This means ! that orc creation, for example, could involve just the following simple steps ! (please note "NPC" is another word for "Mob"):

! !
!
    !
  • create npc new_orc
  • !
  • modify npc name orc
  • !
  • modify orc short a mean-looking orc
  • !
  • modify orc long A typical orc: nasty, brutish, and short.
  • !
  • modify orc race orc
  • !
!
! !

And that's it. All your modifications automatically get written to new_orc.c ! (usually in your area directory), and you now have an npc you can add to a room. ! Adding things to rooms is just as easy. Creating weapons, armor, and other ! objects are done the same way. For complete details and examples, read the ! QCS chapters in the Creators Manual. The QCS section starts in chapter 31.

! !

Example Log

!

Below you will find an excerpt from an short building session using ! Dead Souls. This should be more or less exactly what you'll see by entering ! the commands hilighted in red.

!
! !

The first thing we need to do is get back to our personal work room. We can ! do this using the home command.

! !
! home !
! /realms/testycre/workroom
! Testycre's workroom [e,d]
! You are standing in the workroom of the mighty Testycre!
! You may return to the Creators' Hall by going down.
! A sample room is east.
! There is a sign here you can read.
! There is a sheet here you can read.
! A wooden chest is here.
! 
!
! !

Next, we move east to a sample room that is created automatically for us. ! We'll be experimenting in here.

! !
! east !
! /realms/testycre/area/room/sample_room
! Sample Room [w]
! This is a room you can use as a template.
! A simple table is here.
! A fighter is standing here.
! 
!
! ! !

Room Creation (Back to Top)

!

This is the standard sample room. We're about to create a new room to the ! east of it via the create command.

! !
! create room east test1 !
! It appears you have write access to this area.
! It's a null mapping
! Indenting file...
! "/tmp/indent.1134436511.tmp.dat" 20 lines 330 bytes
! Exit from ed.
! 
! You wave your hand, and a new exit appears.
! You begin uttering a magical incantation.
! Indenting file...
! "/tmp/indent.1134436511.tmp.dat" 27 lines 543 bytes
! Exit from ed.
! 
! Indenting file...
! "/tmp/indent.1134436511.tmp.dat" 27 lines 544 bytes
! Exit from ed.
! 
!
! !

We can now move east to our new room. Notice how it says it's a copy ! of our sample room.

! !
! e !
! /realms/testycre/area/room/test1
! Copy of /realms/testycre/area/room/sample_room.c [w]
! This is a room you can use as a template.
! A simple table is here.
! A fighter is standing here.
! 
!
! !

Now we'll change the short description to avoid confusion between our ! original sample room and the newly created one. Note that a room's short ! description appears as its title or name near the top of the text when a ! user looks at it.

! !
! modify here short Room One !
! Indenting file...
! "/tmp/indent.1134436526.tmp.dat" 27 lines 515 bytes
! Exit from ed.
! 
!
! !

We don't need the fighter from the other room here, so we remove him from ! this new room's inventory.

! !
! delete fighter !
! Indenting
! file...
! "/tmp/indent.1134436532.tmp.dat" 26 lines 507 bytes
! Exit from ed.
! 
! /realms/testycre/area/room/test1: Ok
! /realms/testycre/area/room/test1
! Room One [w]
! This is a room you can use as a template.
! A simple table is here.
! 
! SetInventory modification complete.
! 
!
! !

Now we'll make another room.

! !
! create room east test2 !
! It appears you have write access to this area.
! It's a null mapping
! Indenting file...
! "/tmp/indent.1134436578.tmp.dat" 20 lines 324 bytes
! Exit from ed.
! 
! You wave your hand, and a new exit appears.
! You begin uttering a magical incantation.
! Indenting file...
! "/tmp/indent.1134436578.tmp.dat" 27 lines 557 bytes
! Exit from ed.
! 
! Indenting file...
! "/tmp/indent.1134436578.tmp.dat" 27 lines 525 bytes
! Exit from ed.
! 
!
! !

We'll move east into the newly created room.

! !
! e !
! /realms/testycre/area/room/test2
! Copy of /realms/testycre/area/room/test1.c [w]
! This is a room you can use as a template.
! A simple table is here.
! 
!
! !

Once again, we'll rename our new room.

! !
! modify here short Room 2 !
! Indenting file...
! "/tmp/indent.1134436590.tmp.dat" 26 lines 499 bytes
! Exit from ed.
! 
!
! !

We can now set the room's long description. This will show up as the ! body of the room when a player types look.

! !
! modify here long This is the second test room. !
! Indenting file...
! "/tmp/indent.1134436608.tmp.dat" 26 lines 487 bytes
! Exit from ed.
! 
!
! !

We don't need that table here, let's delete it.

! !
! delete table !
! Indenting file...
! "/tmp/indent.1134436612.tmp.dat" 25 lines 447 bytes
! Exit from ed.
! 
! /realms/testycre/area/room/test2: Ok
! /realms/testycre/area/room/test2
! Room 2 [w]
! This is the second test room.
! SetInventory modification complete.
! 
!
! !

For the sake of self-assurance, we can look at the room's file to make ! sure that our modifications are actually being saved.

! !
! more here !
! #include <lib.h>
! #include "/realms/testycre/customdefs.h"
! 
! inherit LIB_ROOM;
! 
! static void create() {
!  room::create();
!  SetClimate("indoors");
!  SetAmbientLight(30);
!  SetShort("Room 2");
!  SetLong("This is the second test room.");
!  SetExits(([
!  "west" : "/realms/testycre/area/room/test1",
!  ]));
! 
!  SetItems( ([
!  "template" : "That's what this is.",
!  ]) );
! 
!  SetInventory(([
!  ]));
! }
! 
! void init(){
!  ::init();
! }
! 
!
! ! !

NPC Creation (Back to Top)

!

Now we'll create a new NPC (Mob) called "guy". The file name will also ! be "guy".

! !
! create npc guy !
! I'm going to go with the appropriate area directory:
! /realms/testycre/area/npc/guy.c
! You wave your hand mysteriously and a generic npc materializes!
! 
!
! !

We can look at our new room and see the NPC ! standing there.

! !
! l !
! /realms/testycre/area/room/test2
! Room 2 [w]
! This is the second test room.
! A generic npc is standing here.
! 
!
! !

The first thing to do is to rename the new NPC in order to avoid ! confusion. An NPC's name is what the lib refers to the NPC as.

! !
! modify npc name guy !
! Indenting file...
! "/tmp/indent.1134436801.tmp.dat" 15 lines 417 bytes
! Exit from ed.
! 
!
! !

We can now set one or more NPC aliases, called "ids". Note that in the ! following example, we enter three different ones, all of which point to the ! same NPC. A player could look at any of these ! IDs and get the NPC.

! !
! modify npc id !
! This setting takes multiple values. If you have no more values to
! enter, then enter a dot on a blank line. To cancel, enter a single q on a blank
! line.
! You may now enter the next value. So far, it is blank.
! If you're done entering values, enter a dot on a blank line.
! dude
! You may now enter the next value. So far, we have: ({ "dude" })
! If you're done entering values, enter a dot on a blank line.
! fellow
! You may now enter the next value. So far, we have: ({ "dude", "fellow"
! })
! If you're done entering values, enter a dot on a blank line.
! fella
! You may now enter the next value. So far, we have: ({ "dude", "fellow",
! "fella"
! })
! If you're done entering values, enter a dot on a blank line.
! .
! Entries complete. Final array is: ({ "dude", "fellow", "fella" })
! Indenting file...
! "/tmp/indent.1134436831.tmp.dat" 19 lines 442 bytes
! Exit from ed.
! 
! /realms/testycre/tmp/guy1134436805: Ok
! /realms/testycre/area/npc/guy: Ok
! SetId modification complete.
! 
!
! !

Now we'll set the NPCs short description, or name. Any condition such as ! "is standing here" is appended to the end of the NPC's short description, ! so don't end it with a period or any other punctuation.

! !
! modify guy short The Dude !
! Indenting file...
! "/tmp/indent.1134436855.tmp.dat" 19 lines 437 bytes
! Exit from ed.
! 
!
! !

We'll set the long description. This is what is shown when someone actually ! looks directly at the NPC.

! !
! modify guy long This is just some !
! random guy.
! Indenting file...
! "/tmp/indent.1134436904.tmp.dat" 19 lines 408 bytes
! Exit from ed.
! 
!
! !

Adjectives are useful for complementing NPCs and other objects. For example, ! if our guy is 'oily' or 'hairy' as described in his long description, a player ! would be able to do a look oily guy and ! see the guy even if "oily" isn't in his actual name/id.

! !
! modify guy adj !
! This setting takes multiple values. If you have no more values to
! enter, then enter a dot on a blank line. To cancel, enter a single q on a blank
! line.
! You may now enter the next value. So far, it is blank.
! If you're done entering values, enter a dot on a blank line.
! hairy
! You may now enter the next value. So far, we have: ({ "just some" })
! If you're done entering values, enter a dot on a blank line.
! stinky
! You may now enter the next value. So far, we have: ({ "just some",
! "random" })
! If you're done entering values, enter a dot on a blank line.
! oily
! You may now enter the next value. So far, we have: ({ "just some",
! "random",
! "some" })
! If you're done entering values, enter a dot on a blank line.
! .
! Entries complete. Final array is: ({ "just some", "random", "some" })
! Indenting file...
! "/tmp/indent.1134436924.tmp.dat" 19 lines 402 bytes
! Exit from ed.
! 
! /realms/testycre/tmp/guy1134436912: Ok
! /realms/testycre/area/npc/guy: Ok
! SetAdjectives modification complete.
! 
!
! !

Let's look at our room and see if the Dude is appearing as expected.

! !
! look !
! /realms/testycre/area/room/test2
! Room 2 [w]
! This is the second test room.
! The Dude is standing here.
! 
!
! !

We'll check out the Dude's file and see how QCS has set up the NPC for us.

! !
! about dude !
! /realms/testycre/area/npc/guy.c
! 
! #include <lib.h>
! 
! inherit LIB_SENTIENT;
! 
! static void create() {
!  sentient::create();
!  SetKeyName("guy");
!  SetAdjectives( ({"just some", "random", "some"}) );
!  SetId( ({"dude", "fellow", "fella"}) );
!  SetShort("The Dude");
!  SetLong("This is just some random guy.");
!  SetLevel(1);
!  SetRace("human");
!  SetClass("explorer");
!  SetGender("male");
! }
! 
! void init(){
!  ::init();
! 
!
! ! !

Weapon Creation (Back to Top)

!

Now we'll create a weapon for our NPC. "hammer" is the filename.

! !
! create weapon hammer !
! I'm going to go with the appropriate area directory:
! /realms/testycre/area/weap/hammer.c
! You wave your hand mysteriously and a generic weapon materializes!
! 
!
! !

And then set the hammer's ID(s)

! !
! modify weapon id hammer !
! This setting takes multiple values. If you have no more values to
! enter, then enter a dot on a blank line. To cancel, enter a single q on a blank
! line.
! You may now enter the next value. So far, we have: ({ "hammer" })
! If you're done entering values, enter a dot on a blank line.
! warhammer
! You may now enter the next value. So far, we have: ({ "hammer",
! "warhammer" })
! If you're done entering values, enter a dot on a blank line.
! .
! Entries complete. Final array is: ({ "hammer", "warhammer" })
! Indenting file...
! "/tmp/indent.1134437181.tmp.dat" 19 lines 453 bytes
! Exit from ed.
! 
! /realms/testycre/tmp/hammer1134437165: Ok
! /realms/testycre/area/weap/hammer: Ok
! SetId modification complete.
! 
!
! !

And now we will set the weapon's name to "hammer".

! !
! modify weapon name hammer !
! There is no weapon here.
! look
! /realms/testycre/area/room/test2
! Room 2 [w]
! This is the second test room.
! A generic weapon is here.
! The Dude is standing here.
! 
!
! !

What's happened here is that we changed the weapon's ID before the name. ! Luckily, this is easy to fix.

! !
! modify hammer name hammer !
! Indenting file...
! "/tmp/indent.1134437205.tmp.dat" 22 lines 474 bytes
! Exit from ed.
! 
!
! !

Now we'll look at the hammer's file to see how it looks.

! !
! about hammer !
! /realms/testycre/area/weap/hammer.c
! 
! #include <lib.h>
! #include <damage_types.h>
! #include <vendor_types.h>
! 
! inherit LIB_ITEM;
! 
! static void create() {
!  item::create();
!  SetKeyName("hammer");
!  SetId( ({"hammer", "warhammer"}) );
!  SetAdjectives( ({ "generic" }));
!  SetShort("a generic weapon");
!  SetLong("A weapon of indeterminate proportions.");
!  SetMass(50);
!  SetVendorType(VT_WEAPON);
!  SetClass(30);
!  SetDamageType(BLADE);
!  SetWeaponType("blade");
! 
! }
! void init(){
!  ::init();
! }
! 
!
! !

We can now set the hammer's damage type to blunt for a nice crushing ! effect.

! !
! modify hammer damagetype blunt !
! Indenting file...
! "/tmp/indent.1134437392.tmp.dat" 22 lines 474 bytes
! Exit from ed.
! 
!
! !

And now set the weapon type.

! !
! modify hammer weapontype blunt !
! Indenting file...
! "/tmp/indent.1134437398.tmp.dat" 22 lines 474 bytes
! Exit from ed.
! 
!
! !

Similarly, set the mass.

! !
! modify hammer mass 700 !
! Indenting file...
! "/tmp/indent.1134437414.tmp.dat" 22 lines 475 bytes
! Exit from ed.
! 
!
! !

We will now make the weapon require two hands to use.

! !
! modify hammer hands 2 !
! Indenting file...
! "/tmp/indent.1134437422.tmp.dat" 23 lines 492 bytes
! Exit from ed.
! 
!
! !

We'll double-check our hammer's file now to see if everything was set.

! !
! about hammer !
! /realms/testycre/area/weap/hammer.c
! 
! #include <lib.h>
! #include <damage_types.h>
! #include <vendor_types.h>
! 
! inherit LIB_ITEM;
! 
! static void create() {
!  item::create();
!  SetKeyName("hammer");
!  SetId( ({"hammer", "warhammer"}) );
!  SetAdjectives( ({ "generic" }));
!  SetShort("a generic weapon");
!  SetLong("A weapon of indeterminate proportions.");
!  SetHands(2);
!  SetMass(700);
!  SetVendorType(VT_WEAPON);
!  SetClass(30);
!  SetDamageType(BLUNT);
! 
!  SetWeaponType("blunt");
! }
! 
! void init(){
!  ::init();
! }
! 
!
! !

Now we'll set that short description.

! !
! modify hammer short a heavy war hammer !
! Indenting file...
! "/tmp/indent.1134437450.tmp.dat" 23 lines 494 bytes
! Exit from ed.
! 
!
! !

And our long description...

! !
! modify hammer long This is an extremely large and heavy ! hammer designed to be wielded in both hands and used to hurt people very badly ! indeed. !
! Indenting file...
! "/tmp/indent.1134437509.tmp.dat" 23 lines 579 bytes
! Exit from ed.
! 
!
! !

Setting some adjectives.

! !
! modify hammer adj !
! This setting takes multiple values. If you have no more values to
! enter, then enter a dot on a blank line. To cancel, enter a single q on a blank
! line.
! You may now enter the next value. So far, it is blank.
! If you're done entering values, enter a dot on a blank line.
! large
! You may now enter the next value. So far, we have: ({ "large" })
! If you're done entering values, enter a dot on a blank line.
! heavy
! You may now enter the next value. So far, we have: ({ "large", "heavy"
! })
! If you're done entering values, enter a dot on a blank line.
! war
! You may now enter the next value. So far, we have: ({ "large", "heavy",
! "war" })
! If you're done entering values, enter a dot on a blank line.
! .
! Entries complete. Final array is: ({ "large", "heavy", "war" })
! Indenting file...
! "/tmp/indent.1134437531.tmp.dat" 23 lines 592 bytes
! Exit from ed.
! 
! /realms/testycre/tmp/hammer1134437521: Ok
! /realms/testycre/area/weap/hammer: Ok
! SetAdjectives modification complete.
! 
!
! !

And finally, look at our hammer file.

! !
! about hammer !
! /realms/testycre/area/weap/hammer.c
! 
! #include <lib.h>
! #include <damage_types.h>
! #include <vendor_types.h>
! 
! inherit LIB_ITEM;
! 
! static void create() {
!  item::create();
!  SetKeyName("hammer");
!  SetAdjectives( ({"large", "heavy", "war"}) );
!  SetId( ({"hammer", "warhammer"}) );
!  SetShort("a heavy war hammer");
!  SetLong("This is an extremely large and heavy hammer designed to be wielded
!   in both hands and used to hurt people very badly indeed.");
!  SetHands(2);
!  SetMass(700);
!  SetVendorType(VT_WEAPON);
!  SetClass(30);
!  SetDamageType(BLUNT);
! 
!  SetWeaponType("blunt");
! }
! 
! void init(){
!  ::init();
! }
! 
!
! !

It's a pretty heavy hammer, so let's make sure our guy can wield it.

! !
! modify guy level 10 !
! Indenting file...
! "/tmp/indent.1134437557.tmp.dat" 19 lines 403 bytes
! Exit from ed.
! 
!
! !

With this simple command we add the hammer to the permanent inventory of our ! guy.

! !
! add hammer to guy !
! ob2: /realms/testycre/area/npc/guy.c
! ob: /realms/testycre/area/weap/hammer.c
! Please enter a command for the NPC to perform with this item. If you
! have no such command to enter, enter the number of these items you want to add:
! wield hammer
! Indenting file...
! "/tmp/indent.1134437569.tmp.dat" 22 lines 489 bytes
! Exit from ed.
! 
! /realms/testycre/area/npc/guy: Ok
! Guy wields a heavy war hammer.
! SetInventory modification complete.
! 
!
! !

And now we take a look at our guy.

! !
! exa guy !
! This is just some random guy.
! The male human is in top condition.
! Guy is carrying:
! A heavy war hammer (wielded in left hand and right hand)
! 
!
! !

And check the guy's file.

! !
! about guy !
! /realms/testycre/area/npc/guy.c
! 
! #include <lib.h>
! 
! inherit LIB_SENTIENT;
! 
! static void create() {
!  sentient::create();
!  SetKeyName("guy");
!  SetAdjectives( ({"just some", "random", "some"}) );
!  SetId( ({"dude", "fellow", "fella"}) );
!  SetShort("The Dude");
!  SetLong("This is just some random guy.");
!  SetInventory(([
!  "/realms/testycre/area/weap/hammer" : "wield hammer",
!  ]));
!  SetLevel(10);
!  SetRace("human");
!  SetClass("explorer");
!  SetGender("male");
! }
! 
! void init(){
!  ::init();
! }
! 
!
! ! !

Armor Creation (Back to Top)

!

Making armor is just as easy.

! !
! create armor helmet !
! I'm going to go with the appropriate area directory:
! /realms/testycre/area/armor/helmet.c
! You wave your hand mysteriously and generic armor materializes!
! modify armor name helmet
! Indenting file...
! "/tmp/indent.1134437645.tmp.dat" 18 lines 483 bytes
! Exit from ed.
! 
! modify helmet id
! This setting takes multiple values. If you have no more values to
! enter, then enter a dot on a blank line. To cancel, enter a single q on a blank
! line.
! You may now enter the next value. So far, it is blank.
! If you're done entering values, enter a dot on a blank line.
! helm
! You may now enter the next value. So far, we have: ({ "helm" })
! If you're done entering values, enter a dot on a blank line.
! headgear
! You may now enter the next value. So far, we have: ({ "helm",
! "headgear" })
! If you're done entering values, enter a dot on a blank line.
! cover
! You may now enter the next value. So far, we have: ({ "helm",
! "headgear",
! "cover" })
! If you're done entering values, enter a dot on a blank line.
! .
! Entries complete. Final array is: ({ "helm", "headgear", "cover" })
! Indenting file...
! "/tmp/indent.1134437661.tmp.dat" 22 lines 535 bytes
! Exit from ed.
! 
! /realms/testycre/tmp/helmet1134437649: Ok
! /realms/testycre/area/armor/helmet: Ok
! SetId modification complete.
! modify helmet short a horned viking helmet
! Indenting file...
! "/tmp/indent.1134437692.tmp.dat" 22 lines 544 bytes
! Exit from ed.
! 
! modify helmet long Vikings
! didn't really wear horned helmets into combat, but this one does look
! formidable with its large bull horns and thick iron construction. It
! should prove very protective.
! Indenting file...
! "/tmp/indent.1134437772.tmp.dat" 22 lines 666 bytes
! Exit from ed.
! 
! modify helmet adj ! This setting takes multiple values. If you have no more values to ! enter, then enter a dot on a blank line. To cancel, enter a single q on a blank ! line. ! You may now enter the next value. So far, it is blank. ! If you're done entering values, enter a dot on a blank line. ! iron ! You may now enter the next value. So far, we have: ({ "iron" }) ! If you're done entering values, enter a dot on a blank line. ! thick ! You may now enter the next value. So far, we have: ({ "iron", "thick" }) ! If you're done entering values, enter a dot on a blank line. ! viking ! You may now enter the next value. So far, we have: ({ "iron", "thick", ! "viking" ! }) ! If you're done entering values, enter a dot on a blank line. ! horned ! You may now enter the next value. So far, we have: ({ "iron", "thick", ! "viking", ! "horned" }) ! If you're done entering values, enter a dot on a blank line. ! formidable ! You may now enter the next value. So far, we have: ({ "iron", "thick", ! "viking", ! "horned", "formidable" }) ! If you're done entering values, enter a dot on a blank line. ! protective ! You may now enter the next value. So far, we have: ({ "iron", "thick", ! "viking", ! "horned", "formidable", "protective" }) ! If you're done entering values, enter a dot on a blank line. ! . ! Entries complete. Final array is: ({ "iron", "thick", "viking", ! "horned", ! "formidable", "protective" }) ! Indenting file... ! "/tmp/indent.1134437802.tmp.dat" 22 lines 722 bytes ! Exit from ed. ! ! /realms/testycre/tmp/helmet1134437782: Ok ! /realms/testycre/area/armor/helmet: Ok ! SetAdjectives modification complete. ! about helmet ! /realms/testycre/area/armor/helmet.c ! ! #include <lib.h> ! #include <armor_types.h> ! #include <damage_types.h> ! inherit LIB_ARMOR; ! ! static void create(){ ! armor::create(); ! SetKeyName("helmet"); ! SetAdjectives( ({"iron", "thick", "viking", ! "horned", "formidable", ! "protective"}) ); ! SetId( ({"helm", "headgear", "cover"}) ); ! SetShort("a horned viking helmet"); ! SetLong("Vikings didn't really wear horned helmets into combat, but this one ! does look formidable with its large bull horns and thick iron construction. It ! should prove very protective."); ! SetMass(50); ! SetDamagePoints(100); ! SetArmorType(A_BODY_ARMOR); ! SetProtection(BLUNT, 20); ! SetProtection(BLADE, 20); ! SetProtection(KNIFE, 20); ! } ! ! void init(){ ! ::init(); ! } ! modify helmet armortype helmet ! Indenting file... ! "/tmp/indent.1134437818.tmp.dat" 22 lines 718 bytes ! Exit from ed. ! ! modify helmet mass 200 ! Indenting file... ! "/tmp/indent.1134437830.tmp.dat" 22 lines 719 bytes ! Exit from ed. ! ! modify helmet protection ! Your armor can protect against one or more of the following types of ! damage: ! blunt, blade, knife, water, shock, cold, heat, gas, acid, magic, poison, ! disease, trauma, .. ! ! Please enter which ones your armor should protect from, one at a time. ! When you are done, please type a dot on a blank line. ! blunt ! You may now enter the next value. So far, we have: ({ "blunt" }) ! If you're done entering values, enter a dot on a blank line. ! blade ! You may now enter the next value. So far, we have: ({ "blunt", "blade" ! }) ! If you're done entering values, enter a dot on a blank line. ! knife ! You may now enter the next value. So far, we have: ({ "blunt", "blade", ! "knife" ! }) ! If you're done entering values, enter a dot on a blank line. ! trauma ! You may now enter the next value. So far, we have: ({ "blunt", "blade", ! "knife", ! "trauma" }) ! If you're done entering values, enter a dot on a blank line. ! . ! Protections list complete. ! Please enter the protection value for: BLUNT ! 15 ! Please enter the protection value for: BLADE ! 20 ! Please enter the protection value for: KNIFE ! 25 ! Please enter the protection value for: TRAUMA ! 10 ! This is where the mapping gets sent somewhere. ! ProtectionsMap is: ([ "BLADE" : 20, "BLUNT" : 15, "TRAUMA" : 10, ! "KNIFE" : 25 ]) ! Indenting file... ! "/tmp/indent.1134437901.tmp.dat" 23 lines 750 bytes ! Exit from ed. ! ! about helmet ! /realms/testycre/area/armor/helmet.c ! ! #include <lib.h> ! #include <armor_types.h> ! #include <damage_types.h> ! inherit LIB_ARMOR; ! ! static void create(){ ! armor::create(); ! SetKeyName("helmet"); ! SetAdjectives( ({"iron", "thick", "viking", ! "horned", "formidable", ! "protective"}) ); ! SetId( ({"helm", "headgear", "cover"}) ); ! SetShort("a horned viking helmet"); ! SetLong("Vikings didn't really wear horned helmets into combat, but this one ! does look formidable with its large bull horns and thick iron construction. ! It should prove very protective."); ! SetMass(200); ! SetDamagePoints(100); ! SetArmorType(A_HELMET); ! SetProtection(BLADE, 20); ! SetProtection(BLUNT, 15); ! SetProtection(TRAUMA, 10); ! ! SetProtection(KNIFE, 25); ! } ! ! void init(){ ! ::init(); ! } ! l ! /realms/testycre/area/room/test2 ! Room 2 [w] ! This is the second test room. ! A horned viking helmet and a heavy war hammer are here. ! The Dude is standing here. ! ! exa dude ! This is just some random guy. ! The male human is in top condition. ! Guy is carrying: ! A heavy war hammer (wielded in left hand and right hand) ! ! add helmet to dude ! ob2: /realms/testycre/area/npc/guy.c ! ob: /realms/testycre/area/armor/helmet.c ! Please enter a command for the NPC to perform with this item. If you have no ! such command to enter, enter the number of these items you want to add: ! wear helmet ! Indenting file... ! "/tmp/indent.1134437927.tmp.dat" 23 lines 544 bytes ! Exit from ed. ! ! /realms/testycre/area/npc/guy: Ok ! Guy wields a heavy war hammer. ! Guy wears a horned viking helmet. ! SetInventory modification complete. ! exa dude ! This is just some random guy. ! The male human is in top condition. ! Guy is carrying: ! A heavy war hammer (wielded in left hand and right hand) ! A horned viking helmet (worn) !
!
! ! !

Adding Room Resets (Back to Top)

!

Ok our dude is done. Let's clean up the room by updating it.

! !
! update !
! Updating environment
! /realms/testycre/area/room/test2: Ok
! look
! /realms/testycre/area/room/test2
! Room 2 [w]
! This is the second test room.
! pwd
! /realms/testycre:
! cd area/npc
! /realms/testycre/area/npc:
! 
!
! !

We need to have the guy present in order to add him to the room:

! !
! clone guy !
! Guy wields a heavy war hammer.
! Guy wears a horned viking helmet.
! You clone The Dude (/realms/testycre/area/npc/guy.c).
! add guy to room
! ob2: /realms/testycre/area/room/test2.c
! ob: /realms/testycre/area/npc/guy.c
! Please enter the number of these that you want to add:
! 1ook
! Indenting file...
! "/tmp/indent.1134437999.tmp.dat" 26 lines 485 bytes
! Exit from ed.
! 
! /realms/testycre/area/room/test2: Ok
! /realms/testycre/area/room/test2
! Room 2 [w]
! This is the second test room.
! The Dude is standing here.
! 
! SetInventory modification complete.
! update
! Updating environment
! /realms/testycre/area/room/test2: Ok
! 
!
! !

That's it. Easy, huh? Think of how much slogging through ed this would save ! you when making a large area. !

! look !
! /realms/testycre/area/room/test2
! Room 2 [w]
! This is the second test room.
! The Dude is standing here.
! 
! exa dude
! This is just some random guy.
! The male human is in top condition.
! Guy is carrying:
! A heavy war hammer (wielded in left hand and right hand)
! A horned viking helmet (worn)
! 
! more here
! #include <lib.h>
! #include "/realms/testycre/customdefs.h"
! 
! inherit LIB_ROOM;
! 
! static void create() {
!  room::create();
!  SetClimate("indoors");
!  SetAmbientLight(30);
!  SetShort("Room 2");
!  SetLong("This is the second test room.");
!  SetExits(([
!  "west" : "/realms/testycre/area/room/test1",
!  ]));
! 
!  SetItems( ([
!  "template" : "That's what this is.",
!  ]) );
! 
!  SetInventory(([
!  "/realms/testycre/area/npc/guy" : 1,
!  ]));
! }
! 
! void init(){
!  ::init();
! }
! 
! quit
! Please come back another time!
! 
!
! !
!

The End (Back to Top)

!

Obviously you still need to code some LPC in ed for complex stuff. But ! knocking out rooms and NPC's and objects quickly helps you avoid getting bogged ! down in mechanics when what you really want to do is build.

! Return to Dead Souls Homepage ! ! --- 1,739 ---- ! ! ! ! Dead Souls Mudlib - Quick Creation System ! ! ! ! ! ! ! ! ! ! ! !

Index

! !

QCS Described

!

The Quick Creation System (or QCS) is a series of commands and ! modules that lets you create rooms, objects, exits, and NPCs easily and ! quickly. Before the QCS, if you wanted to make an orc, you would edit ! the text file by hand, or copy a template file and use an editor to ! manually change the lines you needed to modify. This could be a ! tiresome process, as the standard editor can be a bit awkward, and ! making dozens of objects this way could be real torture for beginners.

!

The QCS changes all of that. Rather than use an editor to modify ! files, the QCS gives you commands that permit you to modify objects on ! the fly. This means that orc creation, for example, could involve just ! the following simple steps (please note "NPC" is another word for ! "Mob"):

!
!
    !
  • create npc new_orc
  • !
  • modify npc name orc
  • !
  • modify orc short a mean-looking orc
  • !
  • modify orc long A typical orc: nasty, ! brutish, and short.
  • !
  • modify orc race orc
  • !
!
!

And that's it. All your modifications automatically get written to ! new_orc.c (usually in your area directory), and you now have an npc you ! can add to a room. Adding things to rooms is just as easy. Creating ! weapons, armor, and other objects are done the same way. For complete ! details and examples, read the ! QCS chapters in the Creators Manual. The QCS section starts in chapter ! 31.

!

Example Log

!

Below you will find an excerpt from an short building session using ! Dead Souls. This should be more or less exactly what you'll see by ! entering ! the commands hilighted in red.

!
!

The first thing we need to do is get back to our personal work room. ! We can ! do this using the home command.

!
! home !
/realms/testycre/workroom
Testycre's workroom [e,d]
You are standing in the workroom of the mighty Testycre!
You may return to the Creators' Hall by going down.
A sample room is east.
There is a sign here you can read.
There is a sheet here you can read.
A wooden chest is here.
!
!

Next, we move east to a sample room that is created automatically ! for us. ! We'll be experimenting in here.

!
! east
!
!
/realms/testycre/area/room/sample_room
Sample Room [e, w]
This is a room you can use as a template.
A simple table is here.
A fighter is standing here.
!
! !

Room Creation (Back to Top)

!

This is the standard sample room. We're about to create a new room ! to the north of it via the create command.

!
! create room north test1 !
It appears you have write access to this area.
It's a null mapping
Indenting file...
"/tmp/indent.1134436511.tmp.dat" 20 lines 330 bytes
Exit from ed.

You wave your hand, and a new exit appears.
You begin uttering a magical incantation.
Indenting file...
"/tmp/indent.1134436511.tmp.dat" 27 lines 543 bytes
Exit from ed.

Indenting file...
"/tmp/indent.1134436511.tmp.dat" 27 lines 544 bytes
Exit from ed.
!
!

We can now move east to our new room. Notice how it says it's a copy ! of our sample room.

!
! n !
/realms/testycre/area/room/test1
Copy of /realms/testycre/area/room/sample_room.c [s]
This is a room you can use as a template.
A simple table is here.
A fighter is standing here.
!
!

Now we'll change the short description to avoid confusion between ! our ! original sample room and the newly created one. Note that a room's ! short ! description appears as its title or name near the top of the text when ! a ! user looks at it.

!
! modify here short Room One !
Indenting file...
"/tmp/indent.1134436526.tmp.dat" 27 lines 515 bytes
Exit from ed.
!
!

We don't need the fighter from the other room here, so we remove him ! from this new room's inventory.

!
! delete fighter !
Indenting
file...
"/tmp/indent.1134436532.tmp.dat" 26 lines 507 bytes
Exit from ed.

/realms/testycre/area/room/test1: Ok
/realms/testycre/area/room/test1
Room One [w]
This is a room you can use as a template.
A simple table is here.

SetInventory modification complete.
!
!

Now we'll make another room.

!
! create room east test2 !
It appears you have write access to this area.
It's a null mapping
Indenting file...
"/tmp/indent.1134436578.tmp.dat" 20 lines 324 bytes
Exit from ed.

You wave your hand, and a new exit appears.
You begin uttering a magical incantation.
Indenting file...
"/tmp/indent.1134436578.tmp.dat" 27 lines 557 bytes
Exit from ed.

Indenting file...
"/tmp/indent.1134436578.tmp.dat" 27 lines 525 bytes
Exit from ed.
!
!

We'll move east into the newly created room.

!
! e !
/realms/testycre/area/room/test2
Copy of /realms/testycre/area/room/test1.c [w]
This is a room you can use as a template.
A simple table is here.
!
!

Once again, we'll rename our new room.

!
! modify here short Room 2 !
Indenting file...
"/tmp/indent.1134436590.tmp.dat" 26 lines 499 bytes
Exit from ed.
!
!

We can now set the room's long description. This will show up as the ! body of the room when a player types look.

!
! modify here long This is the second test room. !
Indenting file...
"/tmp/indent.1134436608.tmp.dat" 26 lines 487 bytes
Exit from ed.
!
!

We don't need that table here, let's delete it.

!
! delete table !
Indenting file...
"/tmp/indent.1134436612.tmp.dat" 25 lines 447 bytes
Exit from ed.

/realms/testycre/area/room/test2: Ok
/realms/testycre/area/room/test2
Room 2 [w]
This is the second test room.
SetInventory modification complete.
!
!

For the sake of self-assurance, we can look at the room's file to ! make ! sure that our modifications are actually being saved.

!
! more here !
#include <lib.h>
#include "/realms/testycre/customdefs.h"

inherit LIB_ROOM;

static void create() {
room::create();
SetClimate("indoors");
SetAmbientLight(30);
SetShort("Room 2");
SetLong("This is the second test room.");
SetExits(([
"west" : "/realms/testycre/area/room/test1",
]));

SetItems( ([
"template" : "That's what this is.",
]) );

SetInventory(([
]));
}

void init(){
::init();
}
!
! !

NPC Creation (Back to Top)

!

Now we'll create a new NPC (Mob) called "guy". The file name will ! also ! be "guy".

!
! create npc guy !
I'm going to go with the appropriate area directory:
/realms/testycre/area/npc/guy.c
You wave your hand mysteriously and a generic npc materializes!
!
!

We can look at our new room and see ! the NPC ! standing there.

!
! l !
/realms/testycre/area/room/test2
Room 2 [w]
This is the second test room.
A generic npc is standing here.
!
!

The first thing to do is to rename the new NPC in order to avoid ! confusion. An NPC's name is what the lib refers to the NPC as.

!
! modify npc name guy !
Indenting file...
"/tmp/indent.1134436801.tmp.dat" 15 lines 417 bytes
Exit from ed.
!
!

We can now set one or more NPC aliases, called "ids". Note that in ! the ! following example, we enter three different ones, all of which point to ! the ! same NPC. A player could look at any of ! these ! IDs and get the NPC.

!
! modify npc id !
This setting takes multiple values. If you have no more values to
enter, then enter a dot on a blank line. To cancel, enter a single q on a blank
line.
You may now enter the next value. So far, it is blank.
If you're done entering values, enter a dot on a blank line.
dude ! You may now enter the next value. So far, we have: ({ "dude" }) ! If you're done entering values, enter a dot on a blank line. ! fellow ! You may now enter the next value. So far, we have: ({ "dude", "fellow" ! }) ! If you're done entering values, enter a dot on a blank line. ! fella ! You may now enter the next value. So far, we have: ({ "dude", "fellow", ! "fella" ! }) ! If you're done entering values, enter a dot on a blank line. ! . ! Entries complete. Final array is: ({ "dude", "fellow", "fella" }) ! Indenting file... ! "/tmp/indent.1134436831.tmp.dat" 19 lines 442 bytes ! Exit from ed. ! ! /realms/testycre/tmp/guy1134436805: Ok ! /realms/testycre/area/npc/guy: Ok ! SetId modification complete. !
!
!

Now we'll set the NPCs short description, or name. Any condition ! such as ! "is standing here" is appended to the end of the NPC's short ! description, ! so don't end it with a period or any other punctuation.

!
! modify guy short The Dude !
Indenting file...
"/tmp/indent.1134436855.tmp.dat" 19 lines 437 bytes
Exit from ed.
!
!

We'll set the long description. This is what is shown when someone ! actually ! looks directly at the NPC.

!
! modify guy long This is just some random guy !
Indenting file...
"/tmp/indent.1134436904.tmp.dat" 19 lines 408 bytes
Exit from ed.
!
!

Adjectives are useful for complementing NPCs and other objects. For ! example, if our guy is 'oily' or 'hairy' as described in his long ! description, a player ! would be able to do a look oily guy and ! see the guy even if "oily" isn't in his actual name/id.

!
! modify guy adj !
This setting takes multiple values. If you have no more values to
enter, then enter a dot on a blank line. To cancel, enter a single q on a blank
line.
You may now enter the next value. So far, it is blank.
If you're done entering values, enter a dot on a blank line.
hairy ! You may now enter the next value. So far, we have: ({ "just some" }) ! If you're done entering values, enter a dot on a blank line. ! stinky ! You may now enter the next value. So far, we have: ({ "just some", ! "random" }) ! If you're done entering values, enter a dot on a blank line. ! oily ! You may now enter the next value. So far, we have: ({ "just some", ! "random", ! "some" }) ! If you're done entering values, enter a dot on a blank line. ! . ! Entries complete. Final array is: ({ "just some", "random", "some" }) ! Indenting file... ! "/tmp/indent.1134436924.tmp.dat" 19 lines 402 bytes ! Exit from ed. ! ! /realms/testycre/tmp/guy1134436912: Ok ! /realms/testycre/area/npc/guy: Ok ! SetAdjectives modification complete. !
!
!

Let's look at our room and see if the Dude is appearing as expected.

!
! look !
/realms/testycre/area/room/test2
Room 2 [w]
This is the second test room.
The Dude is standing here.
!
!

We'll check out the Dude's file and see how QCS has set up the NPC ! for us.

!
! about dude !
/realms/testycre/area/npc/guy.c

#include <lib.h>

inherit LIB_SENTIENT;

static void create() {
sentient::create();
SetKeyName("guy");
SetAdjectives( ({"just some", "random", "some"}) );
SetId( ({"dude", "fellow", "fella"}) );
SetShort("The Dude");
SetLong("This is just some random guy.");
SetLevel(1);
SetRace("human");
SetClass("explorer");
SetGender("male");
}

void init(){
::init();
!
! !

Weapon Creation (Back to Top)

!

Now we'll create a weapon for our NPC. "hammer" is the filename.

!
! create weapon hammer !
I'm going to go with the appropriate area directory:
/realms/testycre/area/weap/hammer.c
You wave your hand mysteriously and a generic weapon materializes!
!
!

And then set the hammer's ID(s)

!
! modify weapon id hammer !
This setting takes multiple values. If you have no more values to
enter, then enter a dot on a blank line. To cancel, enter a single q on a blank
line.
You may now enter the next value. So far, we have: ({ "hammer" })
If you're done entering values, enter a dot on a blank line.
warhammer ! You may now enter the next value. So far, we have: ({ "hammer", ! "warhammer" }) ! If you're done entering values, enter a dot on a blank line. ! . ! Entries complete. Final array is: ({ "hammer", "warhammer" }) ! Indenting file... ! "/tmp/indent.1134437181.tmp.dat" 19 lines 453 bytes ! Exit from ed. ! ! /realms/testycre/tmp/hammer1134437165: Ok ! /realms/testycre/area/weap/hammer: Ok ! SetId modification complete. !
!
!

And now we will set the weapon's name to "hammer".

!
! modify weapon name hammer !
There is no weapon here.
look ! /realms/testycre/area/room/test2 ! Room 2 [w] ! This is the second test room. ! A generic weapon is here. ! The Dude is standing here. !
!
!

What's happened here is that we changed the weapon's ID before the ! name. ! Luckily, this is easy to fix.

!
! modify hammer name hammer !
Indenting file...
"/tmp/indent.1134437205.tmp.dat" 22 lines 474 bytes
Exit from ed.
!
!

Now we'll look at the hammer's file to see how it looks.

!
! about hammer !
/realms/testycre/area/weap/hammer.c

#include <lib.h>
#include <damage_types.h>
#include <vendor_types.h>

inherit LIB_ITEM;

static void create() {
item::create();
SetKeyName("hammer");
SetId( ({"hammer", "warhammer"}) );
SetAdjectives( ({ "generic" }));
SetShort("a generic weapon");
SetLong("A weapon of indeterminate proportions.");
SetMass(50);
SetVendorType(VT_WEAPON);
SetClass(30);
SetDamageType(BLADE);
SetWeaponType("blade");

}
void init(){
::init();
}
!
!

We can now set the hammer's damage type to blunt for a nice crushing ! effect.

!
! modify hammer damagetype blunt !
Indenting file...
"/tmp/indent.1134437392.tmp.dat" 22 lines 474 bytes
Exit from ed.
!
!

And now set the weapon type.

!
! modify hammer weapontype blunt !
Indenting file...
"/tmp/indent.1134437398.tmp.dat" 22 lines 474 bytes
Exit from ed.
!
!

Similarly, set the mass.

!
! modify hammer mass 700 !
Indenting file...
"/tmp/indent.1134437414.tmp.dat" 22 lines 475 bytes
Exit from ed.
!
!

We will now make the weapon require two hands to use.

!
! modify hammer hands 2 !
Indenting file...
"/tmp/indent.1134437422.tmp.dat" 23 lines 492 bytes
Exit from ed.
!
!

We'll double-check our hammer's file now to see if everything was ! set.

!
! about hammer !
/realms/testycre/area/weap/hammer.c

#include <lib.h>
#include <damage_types.h>
#include <vendor_types.h>

inherit LIB_ITEM;

static void create() {
item::create();
SetKeyName("hammer");
SetId( ({"hammer", "warhammer"}) );
SetAdjectives( ({ "generic" }));
SetShort("a generic weapon");
SetLong("A weapon of indeterminate proportions.");
SetHands(2);
SetMass(700);
SetVendorType(VT_WEAPON);
SetClass(30);
SetDamageType(BLUNT);

SetWeaponType("blunt");
}

void init(){
::init();
}
!
!

Now we'll set that short description.

!
! modify hammer short a heavy war hammer !
Indenting file...
"/tmp/indent.1134437450.tmp.dat" 23 lines 494 bytes
Exit from ed.
!
!

And our long description...

!
! modify hammer long This is an extremely large and ! heavy hammer designed to be wielded in both hands and used to hurt ! people very badly indeed. !
Indenting file...
"/tmp/indent.1134437509.tmp.dat" 23 lines 579 bytes
Exit from ed.
!
!

Setting some adjectives.

!
! modify hammer adj !
This setting takes multiple values. If you have no more values to
enter, then enter a dot on a blank line. To cancel, enter a single q on a blank
line.
You may now enter the next value. So far, it is blank.
If you're done entering values, enter a dot on a blank line.
large ! You may now enter the next value. So far, we have: ({ "large" }) ! If you're done entering values, enter a dot on a blank line. ! heavy ! You may now enter the next value. So far, we have: ({ "large", "heavy" ! }) ! If you're done entering values, enter a dot on a blank line. ! war ! You may now enter the next value. So far, we have: ({ "large", "heavy", ! "war" }) ! If you're done entering values, enter a dot on a blank line. ! . ! Entries complete. Final array is: ({ "large", "heavy", "war" }) ! Indenting file... ! "/tmp/indent.1134437531.tmp.dat" 23 lines 592 bytes ! Exit from ed. ! ! /realms/testycre/tmp/hammer1134437521: Ok ! /realms/testycre/area/weap/hammer: Ok ! SetAdjectives modification complete. !
!
!

And finally, look at our hammer file.

!
! about hammer !
/realms/testycre/area/weap/hammer.c

#include <lib.h>
#include <damage_types.h>
#include <vendor_types.h>

inherit LIB_ITEM;

static void create() {
item::create();
SetKeyName("hammer");
SetAdjectives( ({"large", "heavy", "war"}) );
SetId( ({"hammer", "warhammer"}) );
SetShort("a heavy war hammer");
SetLong("This is an extremely large and heavy hammer designed to be wielded
in both hands and used to hurt people very badly indeed.");
SetHands(2);
SetMass(700);
SetVendorType(VT_WEAPON);
SetClass(30);
SetDamageType(BLUNT);

SetWeaponType("blunt");
}

void init(){
::init();
}
!
!

It's a pretty heavy hammer, so let's make sure our guy can wield it.

!
! modify guy level 10 !
Indenting file...
"/tmp/indent.1134437557.tmp.dat" 19 lines 403 bytes
Exit from ed.
!
!

With this simple command we add the hammer to the permanent ! inventory of our guy.

!
! add hammer to guy !
ob2: /realms/testycre/area/npc/guy.c
ob: /realms/testycre/area/weap/hammer.c
Please enter a command for the NPC to perform with this item. If you
have no such command to enter, enter the number of these items you want to add:
wield hammer ! Indenting file... ! "/tmp/indent.1134437569.tmp.dat" 22 lines 489 bytes ! Exit from ed. ! ! /realms/testycre/area/npc/guy: Ok ! Guy wields a heavy war hammer. ! SetInventory modification complete. !
!
!

And now we take a look at our guy.

!
! exa guy !
This is just some random guy.
The male human is in top condition.
Guy is carrying:
A heavy war hammer (wielded in left hand and right hand)
!
!

And check the guy's file.

!
! about guy !
/realms/testycre/area/npc/guy.c

#include <lib.h>

inherit LIB_SENTIENT;

static void create() {
sentient::create();
SetKeyName("guy");
SetAdjectives( ({"just some", "random", "some"}) );
SetId( ({"dude", "fellow", "fella"}) );
SetShort("The Dude");
SetLong("This is just some random guy.");
SetInventory(([
"/realms/testycre/area/weap/hammer" : "wield hammer",
]));
SetLevel(10);
SetRace("human");
SetClass("explorer");
SetGender("male");
}

void init(){
::init();
}
!
! !

Armor Creation (Back to Top)

!

Making armor is just as easy.

!
! create armor helmet !
I'm going to go with the appropriate area directory:
/realms/testycre/area/armor/helmet.c
You wave your hand mysteriously and generic armor materializes!
modify armor name helmet ! Indenting file... ! "/tmp/indent.1134437645.tmp.dat" 18 lines 483 bytes ! Exit from ed. ! ! modify helmet id ! This setting takes multiple values. If you have no more values to ! enter, then enter a dot on a blank line. To cancel, enter a single q on a blank ! line. ! You may now enter the next value. So far, it is blank. ! If you're done entering values, enter a dot on a blank line. ! helm ! You may now enter the next value. So far, we have: ({ "helm" }) ! If you're done entering values, enter a dot on a blank line. ! headgear ! You may now enter the next value. So far, we have: ({ "helm", ! "headgear" }) ! If you're done entering values, enter a dot on a blank line. ! cover ! You may now enter the next value. So far, we have: ({ "helm", ! "headgear", ! "cover" }) ! If you're done entering values, enter a dot on a blank line. ! . ! Entries complete. Final array is: ({ "helm", "headgear", "cover" }) ! Indenting file... ! "/tmp/indent.1134437661.tmp.dat" 22 lines 535 bytes ! Exit from ed. ! ! /realms/testycre/tmp/helmet1134437649: Ok ! /realms/testycre/area/armor/helmet: Ok ! SetId modification complete. ! modify helmet short a horned viking helmet ! Indenting file... ! "/tmp/indent.1134437692.tmp.dat" 22 lines 544 bytes ! Exit from ed. ! ! modify helmet long Vikings
didn't really wear horned helmets into combat, but this one does look
formidable with its large bull horns and thick iron construction. It
should prove very protective.
! Indenting file... ! "/tmp/indent.1134437772.tmp.dat" 22 lines 666 bytes ! Exit from ed. !
! modify helmet adj ! This setting takes multiple values. If you have no more values to ! enter, then enter a dot on a blank line. To cancel, enter a single q on a blank ! line. ! You may now enter the next value. So far, it is blank. ! If you're done entering values, enter a dot on a blank line. ! iron ! You may now enter the next value. So far, we have: ({ "iron" }) ! If you're done entering values, enter a dot on a blank line. ! thick ! You may now enter the next value. So far, we have: ({ "iron", "thick" }) ! If you're done entering values, enter a dot on a blank line. ! viking ! You may now enter the next value. So far, we have: ({ "iron", "thick", ! "viking" ! }) ! If you're done entering values, enter a dot on a blank line. ! horned ! You may now enter the next value. So far, we have: ({ "iron", "thick", ! "viking", ! "horned" }) ! If you're done entering values, enter a dot on a blank line. ! formidable ! You may now enter the next value. So far, we have: ({ "iron", "thick", ! "viking", ! "horned", "formidable" }) ! If you're done entering values, enter a dot on a blank line. ! protective ! You may now enter the next value. So far, we have: ({ "iron", "thick", ! "viking", ! "horned", "formidable", "protective" }) ! If you're done entering values, enter a dot on a blank line. ! . ! Entries complete. Final array is: ({ "iron", "thick", "viking", ! "horned", ! "formidable", "protective" }) ! Indenting file... ! "/tmp/indent.1134437802.tmp.dat" 22 lines 722 bytes ! Exit from ed. ! ! /realms/testycre/tmp/helmet1134437782: Ok ! /realms/testycre/area/armor/helmet: Ok ! SetAdjectives modification complete. ! about helmet ! /realms/testycre/area/armor/helmet.c ! ! #include <lib.h> ! #include <armor_types.h> ! #include <damage_types.h> ! inherit LIB_ARMOR; ! ! static void create(){ ! armor::create(); ! SetKeyName("helmet"); ! SetAdjectives( ({"iron", "thick", "viking", ! "horned", "formidable", ! "protective"}) ); ! SetId( ({"helm", "headgear", "cover"}) ); ! SetShort("a horned viking helmet"); ! SetLong("Vikings didn't really wear horned helmets into combat, but this one ! does look formidable with its large bull horns and thick iron construction. It ! should prove very protective."); ! SetMass(50); ! SetDamagePoints(100); ! SetArmorType(A_BODY_ARMOR); ! SetProtection(BLUNT, 20); ! SetProtection(BLADE, 20); ! SetProtection(KNIFE, 20); ! } ! ! void init(){ ! ::init(); ! } ! modify helmet armortype helmet ! Indenting file... ! "/tmp/indent.1134437818.tmp.dat" 22 lines 718 bytes ! Exit from ed. ! ! modify helmet mass 200 ! Indenting file... ! "/tmp/indent.1134437830.tmp.dat" 22 lines 719 bytes ! Exit from ed. ! ! modify helmet protection ! Your armor can protect against one or more of the following types of ! damage: ! blunt, blade, knife, water, shock, cold, heat, gas, acid, magic, poison, ! disease, trauma, .. ! ! Please enter which ones your armor should protect from, one at a time. ! When you are done, please type a dot on a blank line. ! blunt ! You may now enter the next value. So far, we have: ({ "blunt" }) ! If you're done entering values, enter a dot on a blank line. ! blade ! You may now enter the next value. So far, we have: ({ "blunt", "blade" ! }) ! If you're done entering values, enter a dot on a blank line. ! knife ! You may now enter the next value. So far, we have: ({ "blunt", "blade", ! "knife" ! }) ! If you're done entering values, enter a dot on a blank line. ! trauma ! You may now enter the next value. So far, we have: ({ "blunt", "blade", ! "knife", ! "trauma" }) ! If you're done entering values, enter a dot on a blank line. ! . ! Protections list complete. ! Please enter the protection value for: BLUNT ! 15 ! Please enter the protection value for: BLADE ! 20 ! Please enter the protection value for: KNIFE ! 25 ! Please enter the protection value for: TRAUMA ! 10 ! This is where the mapping gets sent somewhere. ! ProtectionsMap is: ([ "BLADE" : 20, "BLUNT" : 15, "TRAUMA" : 10, ! "KNIFE" : 25 ]) ! Indenting file... ! "/tmp/indent.1134437901.tmp.dat" 23 lines 750 bytes ! Exit from ed. ! ! about helmet ! /realms/testycre/area/armor/helmet.c ! ! #include <lib.h> ! #include <armor_types.h> ! #include <damage_types.h> ! inherit LIB_ARMOR; ! ! static void create(){ ! armor::create(); ! SetKeyName("helmet"); ! SetAdjectives( ({"iron", "thick", "viking", ! "horned", "formidable", ! "protective"}) ); ! SetId( ({"helm", "headgear", "cover"}) ); ! SetShort("a horned viking helmet"); ! SetLong("Vikings didn't really wear horned helmets into combat, but this one ! does look formidable with its large bull horns and thick iron construction. ! It should prove very protective."); ! SetMass(200); ! SetDamagePoints(100); ! SetArmorType(A_HELMET); ! SetProtection(BLADE, 20); ! SetProtection(BLUNT, 15); ! SetProtection(TRAUMA, 10); ! ! SetProtection(KNIFE, 25); ! } ! ! void init(){ ! ::init(); ! } ! l ! /realms/testycre/area/room/test2 ! Room 2 [w] ! This is the second test room. ! A horned viking helmet and a heavy war hammer are here. ! The Dude is standing here. ! ! exa dude ! This is just some random guy. ! The male human is in top condition. ! Guy is carrying: ! A heavy war hammer (wielded in left hand and right hand) ! ! add helmet to dude ! ob2: /realms/testycre/area/npc/guy.c ! ob: /realms/testycre/area/armor/helmet.c ! Please enter a command for the NPC to perform with this item. If you have no ! such command to enter, enter the number of these items you want to add: ! wear helmet ! Indenting file... ! "/tmp/indent.1134437927.tmp.dat" 23 lines 544 bytes ! Exit from ed. ! ! /realms/testycre/area/npc/guy: Ok ! Guy wields a heavy war hammer. ! Guy wears a horned viking helmet. ! SetInventory modification complete. ! exa dude ! This is just some random guy. ! The male human is in top condition. ! Guy is carrying: ! A heavy war hammer (wielded in left hand and right hand) ! A horned viking helmet (worn) !
!
! !

Adding Room Resets (Back to Top)

!

Ok our dude is done. Let's clean up the room by updating it.

!
! update !
Updating environment
/realms/testycre/area/room/test2: Ok
look ! /realms/testycre/area/room/test2 ! Room 2 [w] ! This is the second test room. ! pwd ! /realms/testycre: ! cd area/npc ! /realms/testycre/area/npc: !
!
!

We need to have the guy present in order to add him to the room:

!
! clone guy !
Guy wields a heavy war hammer.
Guy wears a horned viking helmet.
You clone The Dude (/realms/testycre/area/npc/guy.c).
add guy to room ! ob2: /realms/testycre/area/room/test2.c ! ob: /realms/testycre/area/npc/guy.c ! Please enter the number of these that you want to add: ! 1
Indenting file... ! "/tmp/indent.1134437999.tmp.dat" 26 lines 485 bytes ! Exit from ed. ! ! /realms/testycre/area/room/test2: Ok ! /realms/testycre/area/room/test2 ! Room 2 [w] ! This is the second test room. ! The Dude is standing here. ! ! SetInventory modification complete. ! update ! Updating environment ! /realms/testycre/area/room/test2: Ok !
!
!

That's it. Easy, huh? Think of how much slogging through ed this ! would save you when making a large area. !

!
look !
/realms/testycre/area/room/test2
Room 2 [w]
This is the second test room.
The Dude is standing here.

exa dude ! This is just some random guy. ! The male human is in top condition. ! Guy is carrying: ! A heavy war hammer (wielded in left hand and right hand) ! A horned viking helmet (worn) ! ! more here ! #include <lib.h> ! #include "/realms/testycre/customdefs.h" ! ! inherit LIB_ROOM; ! ! static void create() { ! room::create(); ! SetClimate("indoors"); ! SetAmbientLight(30); ! SetShort("Room 2"); ! SetLong("This is the second test room."); ! SetExits(([ ! "west" : "/realms/testycre/area/room/test1", ! ])); ! ! SetItems( ([ ! "template" : "That's what this is.", ! ]) ); ! ! SetInventory(([ ! "/realms/testycre/area/npc/guy" : 1, ! ])); ! } ! ! void init(){ ! ::init(); ! } ! ! quit ! Please come back another time! !
!
!
!

The End (Back to Top)

!

Obviously you still need to code some LPC in ed for complex stuff. ! But knocking out rooms and NPC's and objects quickly helps you avoid ! getting bogged down in mechanics when what you really want to do is ! build.

! Return to Dead Souls Homepage ! ! diff -c -r --new-file ds2.0r26/lib/www/hotfix.html ds2.0r29/lib/www/hotfix.html *** ds2.0r26/lib/www/hotfix.html Sun Jun 18 16:08:43 2006 --- ds2.0r29/lib/www/hotfix.html Fri Jul 7 19:41:43 2006 *************** *** 25,45 ****

All of the fixes listed here will be included in the next release. They are provided here early in order to address potential problems.

!

For Dead Souls 2.0r25, the following fixes are available:

    !
  • There is a serious security problem that ! affects all versions of Dead Souls. I'll be accelerating the release of ! the next version, and will be trying to get a hotfix out as quickly as ! possible. Until then, do not promote anyone to the position of Creator ! unless you know them very very well. If you already have Creators you ! don't know well, lock the mud (admintool option a) until you can ! upgrade or apply the patch. Sorry, guys. I'm hoping to have it out by ! Saturday, or Sunday at the latest.
Binary files ds2.0r26/lib/www/lpuni_afiliated.png and ds2.0r29/lib/www/lpuni_afiliated.png differ diff -c -r --new-file ds2.0r26/lib/www/news.html ds2.0r29/lib/www/news.html *** ds2.0r26/lib/www/news.html Sun Jun 18 16:08:46 2006 --- ds2.0r29/lib/www/news.html Fri Jul 7 19:41:45 2006 *************** *** 19,24 **** --- 19,240 ----

+ 07 July 06
+
+     A really surprising thing happened today. I
+ decided to reorganize my .plan file and remove
+ anything that wasn't either an important feature
+ enhancement or a bugfix. I wanted to know *exactly*
+ how close I am to releasing Dead Souls 2.1.
+
+     After slogging through and tearing out pages
+ of wishlists and maybes, this is what was left:
+
+ - fix /obj/stargate
+ - update colors with %%^^ data
+ - verbify force
+ - can't delete glass case?
+ - are people defaulting to the start room?
+ - sell machine to cat
+ - make an npc's living body go away BEFORE the corpse is moved into the + room
+ - make channels understand ) after : can have non emote messages after
+ - SetMaxHealth shouldn't need to be in init()
+ - help area
+ - help newbie
+ - apostrophes
+ - add damage types to dummy
+ - intergossip logging to two files?
+ - review setinventory, is addstuff necessary?
+ - Beggar says in English, "Hi, A mangy little rat."
+ - shop in the town is confusing the maglite with the cheap one.
+ - If a piece of gear is set for a "left foot" attribute, why can I also + wear it on my right foot?
+ - the handbook says that its easier to kill things as a mage,
+ - bug: cp sefun.c  /
+ - delete mfinger
+ - SetEmptyName(), SetEmptyLong() and SetEmptyShort().
+ - install faq: if compile problems, try as root, try non 64bit amd
+ - wipe the unused tc's
+
+     That's it. Now compare the size of this list with
+ the size of stuff in the release + notes. That's how close
+ I am. I was shocked.
+
+     So folks, I need your help. Any bugs that have been
+ bothering you but you haven't gotten around to telling me,
+ this is the time. If you feel like knocking about the code
+ trying to break stuff, please log into the demo mud
+ at rugose.com 6666 and have at + it.
+
+     It's ok that you'll make the list longer. That's
+ what I *want*. I want to get these bufixes as over with
+ as possible.
+
+
+ 06 July 06
+
+ more update news:
+
+     I overlooked a couple of important things when
+ I released 2.0r27. They have been addressed in
+ 2.0r28.
+
+     There may be a compat buster here. One of the
+ things that needed fixing was a peculiar bug that
+ would generate extra corpses under unusual circumstances,
+ during combat. This bug had some relationship to
+ another combat bug that prevented the accurate
+ recording of a player's deaths.
+
+     In the end, the fixes for these two involved the
+ manipulation of persistent player variables. The
+ good news is that things now seem to work just fine,
+ and the bugs are seemingly gone.
+
+     The bad news is that since new player variables
+ are involved, you may find that test chars created
+ before an upgrade to r28 do weird things in combat...
+ like not fight.
+
+     The fix is to create new test chars.
+
+     If Dead Souls was widespread enough that that
+ there were muds out there that were open, with players,
+ I'd look into some sort of system for updating
+ older player files. Since this is not the case,
+ I expect that people will be able to tolerate this
+ minor inconvenience with minimal discomfort.
+
+
+
+ 05 July 2006
+
+ router news:
+     The gjs router has been down for a week now, and
+ we may see some refugee muds start to make their
+ home on our router, yatmim (which by the way, stands
+ for Yet Another TMI Mud, which is how the router
+ started out. It's a DS mud now.) Yatmim is public and
+ so all are welcome, but there are some rules folks
+ need to abide by. The point of yatmim was to have
+ a reliable router for DS muds, but also one where
+ new people wouldn't be afraid to ask for help.
+
+     Please see the new router rules page + for more info.
+
+ update news:
+     Version 2.0r27 is out. I'm ever grateful to the
+ folks who find problems and report them...without
+ their help Dead Souls would take much longer to
+ get where it's going. Thanks, guys.
+
+     It probably still has a bug or two, specifically in
+ message boards. As usual, hotfixes will be posted
+ on the hotfix page. As + usual, please let me know what
+ bugs you find.
+
+     One of the new features in r27 is that the install
+ process will now work on Wolfpaw servers, so you folks
+ staying away because you couldn't get it to work, come
+ on in. The water's fine. Just be sure to run make -j 1
+ instead of just make.
+
+     For those uncomfortable with frequent patching,
+ please be aware that it isn't absolutely necessary.
+ See the patch + article for more details.
+
+     Note that for those unwilling to follow the
+ standard patch procedure, diffs are being made
+ available here.
+
+ LPUni news:
+     Tacitus has made some improvements to the front page.
+ Let's hope he keeps that up and fleshes out the rough
+ draft we see today.
+
+     He has also set up a "mud farm", with various LP
+ lib flavors running. Take a look in particular at the
+ Dead Souls 1.1 mud he's hosting. It should be interesting
+ to see how different it is from DS2. The address is:
+ lpuni.org 6501
+
+
+ Sourceforge news:
+     In case you haven't noticed, I'm relying less
+ and less on Sourceforge. They're great and everything,
+ but lately they've been down a lot, and it made me
+ realize I'm depending on them for stuff I can do
+ myself. The download stats are totally misleading,
+ and all their fancy project management stuff is just
+ a waste on me.
+     So you can pretty much figure on releases and
+ patches showing up here first and more often than
+ on Sourceforge.
+    
+
+ 23 June 2006
+
+     I've been frustrated for some time with the way
+ the LPUniversity site seems almost intentionally
+ designed to be confusing and inscrutable to newbie
+ mudders. For example, if I didn't happen to know
+ the site is supposed to be an LPC mud resource, the
+ front page wouldn't be much help in informing me.
+
+     So I bought a domain with the single purpose
+ of clarifying things. It's a shame I had to take it
+ upon myself, but you know what they say about things
+ done right.
+
+     The lpmuds.net site + is intended to be a simple,
+ easy-to-read description of LP muds. What they are,
+ where you can get some, and where you can go to
+ talk about them. None of this fancy calendaring,
+ plenipotentiary council executive meetings, soup for
+ the needy, whatever.
+
+     It's just a web site with information that I
+ hope is useful.
+
+     If you have any suggestions or requests about
+ what the site should have, please let me know.
+
+     On another note, please be aware that Dead Souls
+ is no longer GPL. For more information, please see
+ this + article.
+
+     Saquivor has found a neat creation GUI that he's
+ adapting for DS use. Keep an eye on the downloads page
+ for a DS template. It should be available soon.
+
+
+ 18 June 2006
+
+     The 2.0r26 + patch is out. Anyone under that rev is
+ subject to having their mud compromised by any creator
+ at any time. Please upgrade NOW if + you haven't already
+ done so.
+
+     As to the issue of Tacitus, please see this link.
+
+
16 June 2006

    As usual, good news and bad news. The good news diff -c -r --new-file ds2.0r26/lib/www/router.html ds2.0r29/lib/www/router.html *** ds2.0r26/lib/www/router.html Sun Jun 18 16:08:47 2006 --- ds2.0r29/lib/www/router.html Sun Jul 9 19:04:31 2006 *************** *** 4,13 **** Dead Souls I3 router - -
--- 4,13 ---- Dead Souls I3 router + +
*************** *** 19,49 **** Dead Souls Intermud3 Router
!
!
This page is for folks ! already using Dead Souls and modifying
!
! !
their intermud configuration. If ! this does not apply to you, please
! return to the main site for general ! information:
!

-
- - Or the following FAQs:
-
-
The General FAQ  http://dead-souls.net/ds-faq.html
-
-
The Admin FAQ  http://dead-souls.net/ds-admin-faq.html
-
-
The Creator FAQ: http://dead-souls.net/ds-creator-faq.html
-
-
The Installation FAQ: http://dead-souls.net/ds-inst-faq.html
-

-
What is the Dead Souls router? It's an intermud protocol version 3
--- 19,26 ---- Dead Souls Intermud3 Router

!

What is the Dead Souls router? It's an intermud protocol version 3
*************** *** 52,57 **** --- 29,41 ---- was written by the legendary Tim@TimMUD.

+
+ What are + the rules?
+
+ Please read the router + rules page.
+

Is it private?
*************** *** 72,78 **** style="font-weight: bold;"> 23


!
How do I set it up?

To --- 56,71 ---- style="font-weight: bold;"> 23


!
Is ! is "secure"?
!
!
Nope. Read this: http://dead-souls.net/ds-admin-faq.html#90
!
Bottom line: Don't tell secrets on the router.
!
! How do I set it up?


To *************** *** 90,96 **** security. The router resets frequently, and on that
reset, your mud will be authenticated. Just be patient.
If it's been more than a day or so, email me at
! <my name here>@users.sourceforge.net


What's the --- 83,103 ---- security. The router resets frequently, and on that
reset, your mud will be authenticated. Just be patient.
If it's been more than a day or so, email me at
! <my name here>@comcast.net
!
!     Also note, the name is yatmim, with an M at the end
! and not an N. It stands for ! Yet Another TMI Mud. yatmim.
! Lower case letters. I'll see if I can make the router
! more forgiving of that typo.
!
!     Getting the router name wrong is the number one ! cause of
! errors. Also, once you get it wrong, your own client
! cache might keep the old one, even if you change your
! intermud client code. Make sure you purge the i3 data
! cache before you try again.


What's the *************** *** 208,221 ****
!
More technical docs:
! Creator FAQ             ! Debugging FAQ         ! Editor Tutorial     !   !   The Quick Creation System         !

--- 215,225 ----
!
!
Dead Souls Home
!
diff -c -r --new-file ds2.0r26/lib/www/router_rules.html ds2.0r29/lib/www/router_rules.html *** ds2.0r26/lib/www/router_rules.html Wed Dec 31 19:00:00 1969 --- ds2.0r29/lib/www/router_rules.html Sat Jul 8 23:31:01 2006 *************** *** 0 **** --- 1,145 ---- + + + + Dead Souls I3 router + + + + + + +
+ +
+
+
+
+
Dead + Souls Router Rules
+
+
+
+
1) The point of this + router being up is not free speech.
+
+ 2) This router is up for the + following purposes:
+
+     * To provide technical help for LP muds.
+     * To provide a friendly space for chat between muds.
+     * To test and improve mud communication systems, + such as intermud mail.
+
+ 3) The router is not up for + testing security of an I3 router. Attempting
+    to exploit the router is not ok, and not "cool". If + you find
+    a security weakness please email me so I can handle it + discreetly.
+    You will get full credit for the discovery when the patch + comes out.
+
+ 4) The following channels are + reserved for the topics described below:
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
dsDead Souls mud code talk
ds_testtesting testing 1, 2, 3, etc
intergossipgeneral offtopic stuff
lpuniLPUniversity discussion
intercregeneral technical chatter
+
+

+ 5) The following are not + tolerated on those channels: hate speech, social engineering
+    hacks, unwarranted hostility to newbies, spamming, + commercial advertising. All of
+    these will be judged by my subjective opinion of what + constitutes a violation.
+    Types of violations can be added to this list without + warning by me.
+
+ 6) You may create up to 8 + intermud channels for your mud. These channels can
+    have any content you want that is permissible by all + applicable laws. I
+    don't want to control the intermud with an iron hand. I + just want those five
+    channels listed above to be a safe place for newbies to + congregate, socialize,
+    and/or get work done.
+
+ 7) If you don't like these + rules, set up your own router. Or go play on the
+    gjs router, if ever it comes back up.
+
+ 8) I will not help or support + you in any way in setting up a router, or
+    in creating a channel for your mud. These undocumented + procedures require
+    expertise to accomplish that you have to earn on your own + by reading
+    the code on your mud and the i3 specs ( intermud.org ).
+
+ 9) I will not ban a mud just + because of your tattle tales. I expect you
+    to handle your own personal problems. If someone bugs you, + use the earmuff
+    command. Earmuff the person, or earmuff the mud, or just + stay off the
+    channel in question. The chances I'll step into something + like this
+    are slight, so don't look to me to solve your online + disputes. I'm
+    your Dutch uncle, not your coddling mommy.
+
+
+
+ Note: I'm not normally this + harsh or fascistic. I just want to make things clear
+ right from the start, because I refuse to get into who was
+ mean to whom on what channel. It's a waste of everyone's time. If you + break
+ the rules, I will probably ask you politely to stop, or I may just
+ ban you. Please be reasonable and play nice, or don't come into my + house.
+

+ - Cratylus <my name here> @comcast.net
+
+
+
Dead Souls Home  +
+
+
+
+
+
+
+
+
+ + diff -c -r --new-file ds2.0r26/lib/www/verbs.html ds2.0r29/lib/www/verbs.html *** ds2.0r26/lib/www/verbs.html Sun Jun 18 16:08:49 2006 --- ds2.0r29/lib/www/verbs.html Wed Jul 5 00:00:59 2006 *************** *** 9,15 ****
The Verb


The verb is like anything else. Exactly as
good as you make it, no more and no less. Deconstructing
a new verb for the first time can be confusing, but
in doing so you will gain a better understanding of
the parsing system Dead Souls uses.

Please note, if there's anything here hard to
follow or understand, you need to review the Creator's
Manual for key LPC concepts.


The verb itself

Rules and tokens

can's and do's

The objects

References


The Verb

Note: This page is for advanced coders who need to
create new verbs, or modify existing ones. Newbie
coders should not assume they need to know everything
here.

The verb is like anything else. Exactly as
good as you make it, no more and no less. Deconstructing
a new verb for the first time can be confusing, but
in doing so you will gain a better understanding of
the parsing system Dead Souls uses.

Please note, if there's anything here hard to
follow or understand, you need to review the Creator's
Manual for key LPC concepts.


The verb itself

Rules and tokens

can's and do's

The objects

References