# # Patch name: chown+clone_preserve.patch # Patch version: 1 # Author's name: Kurt Fitzner # Author's email: kfitzner@nexus.v-wave.com # Version of PennMUSH: 1.7.2p24 # Date patch made: Wed Apr 7 14:28:01 1999 # Author is willing to support (yes/no): yes # Patch format: diff -u5 # # # This is a contributed PennMUSH patch. Its use is subject to the # same restrictions found in PennMUSH's hdrs/copyrite.h file. # # No warranty is given for this patch. It is not necessarily going # to work on your system, with any version of PennMUSH other than # the one above, etc. # # If the author given above was willing to support the patch, you # should write to the author if you have any questions or problems. Do # *NOT* send email messages to Javelin or any PennMUSH mailing list about # this patch! # # Below this line is the author's description of the patch, # followed by the patch itself. If the patch is in context diff # format, you'll probably apply it by typing: patch < patchfile # in your top-level MUSH directory, unless instructed otherwise # below. # # chown+clone_preserve.patch # Adds /preserve flag to @clone and @chown. This allows a wiz # to @chown or @clone an object without stripping it of all its # powers and settings. See help file chanes in patch for # details. # # This patch (or perhaps something like it) is scheduled for # inclusion in PennMUSH 1.7.3. # diff -u5 ../testmush/hdrs/externs.h hdrs/externs.h --- ../testmush/hdrs/externs.h Sat Apr 3 10:32:18 1999 +++ hdrs/externs.h Wed Apr 7 14:28:01 1999 @@ -143,11 +143,11 @@ extern dbref do_create _((dbref player, char *name, int cost)); extern dbref do_real_open _((dbref player, const char *direction, const char *linkto, dbref pseudo)); extern void do_open _((dbref player, const char *direction, char **links)); extern void do_link _((dbref player, const char *name, const char *room_name)); extern void do_unlink _((dbref player, const char *name)); -extern dbref do_clone _((dbref player, char *name)); +extern dbref do_clone _((dbref player, char *name, int preserve)); /* From flags.c */ extern const char *unparse_flags _((dbref thing, dbref player)); extern const char *flag_description _((dbref player, dbref thing)); extern object_flag_type find_flag _((char *name, int type, int *toggle, int is_conf)); @@ -256,11 +256,11 @@ extern void do_edit _((dbref player, dbref thing, char *q, char **argv)); extern void do_chzone _((dbref player, const char *name, const char *newobj)); extern void do_parent _((dbref player, char *name, char *parent_name)); extern int do_set _((dbref player, const char *name, char *flag)); extern void do_name _((dbref player, const char *name, char *newname)); -extern void chown_object _((dbref player, dbref thing, dbref newowner)); +extern void chown_object _((dbref player, dbref thing, dbref newowner, int preserve)); extern void do_wipe _((dbref player, char *name)); /* From speech.c */ extern void ns_esnotify _((char *dest, dbref speaker, dbref (*func) (), void *fdata)); extern void notify_except _((dbref first, dbref exception, const char *msg)); diff -u5 ../testmush/hdrs/game.h hdrs/game.h --- ../testmush/hdrs/game.h Fri Apr 2 10:54:29 1999 +++ hdrs/game.h Wed Apr 7 14:18:31 1999 @@ -129,11 +129,11 @@ extern void do_rpage_list(); #endif /* ALLOW_RPAGE */ /* From set.c */ extern void do_name _((dbref player, const char *name, char *newname)); -extern void do_chown _((dbref player, const char *name, const char *newobj)); +extern void do_chown _((dbref player, const char *name, const char *newobj, int preserve)); extern void do_chzone _((dbref player, const char *name, const char *newobj)); extern int do_set _((dbref player, const char *name, char *flag)); extern void do_cpattr _((dbref player, char *oldpair, char **newpair, int move)); extern void do_gedit _((dbref player, char *it, char **argv)); extern void do_trigger _((dbref player, char *object, char **argv)); diff -u5 ../testmush/src/SWITCHES src/SWITCHES --- ../testmush/src/SWITCHES Fri Apr 2 10:55:33 1999 +++ src/SWITCHES Tue Apr 6 22:46:30 1999 @@ -71,10 +71,11 @@ PANIC PARANOID PLAYERS PORT POSE +PRESERVE PRINT PRIVS PURGE QUICK QUIET diff -u5 ../testmush/src/cmds.c src/cmds.c --- ../testmush/src/cmds.c Fri Apr 2 10:54:47 1999 +++ src/cmds.c Wed Apr 7 14:27:07 1999 @@ -140,11 +140,14 @@ COMMAND (cmd_chownall) { do_chownall(player, arg_left, arg_right); } COMMAND (cmd_chown) { - do_chown(player, arg_left, arg_right); + if (SW_ISSET(sw, SWITCH_PRESERVE)) + do_chown(player, arg_left, arg_right, SWITCH_PRESERVE); + else + do_chown(player, arg_left, arg_right, SWITCH_NONE); } COMMAND (cmd_chzoneall) { do_chzoneall(player, arg_left, arg_right); } @@ -179,11 +182,14 @@ COMMAND (cmd_create) { do_create(player, arg_left, atol(arg_right)); } COMMAND (cmd_clone) { - do_clone(player, arg_left); + if (SW_ISSET(sw, SWITCH_PRESERVE)) + do_clone(player, arg_left, SWITCH_PRESERVE); + else + do_clone(player, arg_left, SWITCH_NONE); } #ifdef CHAT_SYSTEM COMMAND (cmd_clock) { if (SW_ISSET(sw, SWITCH_JOIN)) diff -u5 ../testmush/src/command.c src/command.c --- ../testmush/src/command.c Tue Apr 6 20:18:52 1999 +++ src/command.c Wed Apr 7 14:28:38 1999 @@ -70,17 +70,17 @@ #endif {"@CHANNEL", "LIST ADD DELETE RENAME NAME PRIVS QUIET DECOMPILE DESC CHOWN WIPE MUTE GAG HIDE WHAT TITLE", cmd_channel, CMD_T_ANY | CMD_T_SWITCHES | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0, 0}, {"@CHAT", NULL, cmd_chat, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0, 0}, #endif {"@CHOWNALL", NULL, cmd_chownall, CMD_T_ANY | CMD_T_EQSPLIT, WIZARD, 0, 0}, - {"@CHOWN", NULL, cmd_chown, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0, 0}, + {"@CHOWN", "PRESERVE", cmd_chown, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0, 0}, {"@CHZONEALL", NULL, cmd_chzoneall, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0, 0}, {"@CHZONE", NULL, cmd_chzone, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0, 0}, {"@CONFIG", "LIST GLOBALS DEFAULTS COSTS FUNCTIONS COMMANDS ATTRIBS", cmd_config, CMD_T_ANY, 0, 0, 0}, {"@CPATTR", NULL, cmd_cpattr, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS, 0, 0, 0}, {"@CREATE", NULL, cmd_create, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0, 0}, - {"@CLONE", NULL, cmd_clone, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0, 0}, + {"@CLONE", "PRESERVE", cmd_clone, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0, 0}, #ifdef CHAT_SYSTEM {"@CLOCK", "JOIN SPEAK MOD SEE HIDE", cmd_clock, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0, 0}, #endif {"@DBCK", NULL, cmd_dbck, CMD_T_ANY, WIZARD, 0, 0}, {"@DECOMPILE", "DB TF FLAGS ATTRIBS", cmd_decompile, CMD_T_ANY, 0, 0, 0}, diff -u5 ../testmush/src/create.c src/create.c --- ../testmush/src/create.c Fri Apr 2 10:54:53 1999 +++ src/create.c Wed Apr 7 14:33:53 1999 @@ -27,11 +27,11 @@ void do_open _((dbref player, const char *direction, char **links)); void do_unlink _((dbref player, const char *name)); void do_link _((dbref player, const char *name, const char *room_name)); dbref do_dig _((dbref player, const char *name, char **argv, int tport)); dbref do_create _((dbref player, char *name, int cost)); -dbref do_clone _((dbref player, char *name)); +dbref do_clone _((dbref player, char *name, int preserve)); /* utility for open and link */ static dbref parse_linkable_room(player, room_name) dbref player; @@ -280,11 +280,11 @@ ((a == 1) ? MONEY : MONIES))); return; } else { /* pay the owner for his loss */ giveto(Owner(thing), EXIT_COST); - chown_object(player, thing, player); + chown_object(player, thing, player, 0); } } /* link has been validated and paid for; do it */ Owner(thing) = Owner(player); @@ -469,13 +469,14 @@ } return NOTHING; } dbref -do_clone(player, name) +do_clone(player, name, preserve) dbref player; char *name; + int preserve; { dbref clone, thing; if (Guest(player)) { notify(player, "Guests are not allowed to build."); @@ -492,10 +493,14 @@ /* don't allow cloning of destructed things */ if (IsGarbage(thing)) { notify(player, "There's nothing left of it to clone!"); return NOTHING; } + if (preserve && !Wizard(player)) { + notify(player, "You cannot @CLONE/PRESERVE. Use normal @CLONE instead."); + return NOTHING; + } /* make sure owner can afford it */ switch (Typeof(thing)) { case TYPE_THING: if (RESTRICTED_BUILDING && !FREE_OBJECTS && !Builder(player)) { notify(player, "Command is for builders only."); @@ -518,24 +523,34 @@ add_lock(clone, ll->type, dup_bool(ll->key)); } } Zone(clone) = Zone(thing); Parent(clone) = Parent(thing); - Flags(clone) &= ~WIZARD; + if (!preserve) { + Flags(clone) &= ~WIZARD; +#ifdef ROYALTY_FLAG + Flags(clone) &= ~ROYALTY; +#endif +#ifdef USE_WARNINGS + Warnings(clone) = 0; /* zap warnings */ +#endif + Powers(clone) = 0; /* zap powers */ + } + if (Wizard(clone) || #ifdef ROYALTY_FLAG - Flags(clone) &= ~ROYALTY; + Royalty(clone) || #endif #ifdef USE_WARNINGS - Warnings(clone) = 0; /* zap warnings */ + Warnings(clone) || #endif + Powers(clone)) + notify(player, "Warning: @CLONE/PRESERVE on an object with WIZ, ROY, @Powers, or Warnings."); #ifdef CREATION_TIMES /* We give the clone the same modification time that its * other clone has, but update the creation time */ CreTime(clone) = time((time_t *) 0); #endif - Powers(clone) = 0; /* zap powers */ - Contents(clone) = Location(clone) = Next(clone) = NOTHING; notify(player, tprintf("Cloned: Object #%d.", clone)); moveto(clone, Location(player)); #ifdef LOCAL_DATA LocData(clone) = NULL; @@ -564,18 +579,29 @@ } } Zone(clone) = Zone(thing); Parent(clone) = Parent(thing); Flags(clone) = Flags(thing); - Flags(clone) &= ~WIZARD; + if (!preserve) { + Flags(clone) &= ~WIZARD; +#ifdef ROYALTY_FLAG + Flags(clone) &= ~ROYALTY; +#endif +#ifdef USE_WARNINGS + Warnings(clone) = 0; /* zap warnings */ +#endif + Powers(clone) = 0; /* zap powers */ + } + if (Wizard(clone) || #ifdef ROYALTY_FLAG - Flags(clone) &= ~ROYALTY; + Royalty(clone) || #endif #ifdef USE_WARNINGS - Warnings(clone) = 0; /* zap warnings */ + Warnings(clone) || #endif - Powers(clone) = 0; /* zap powers */ + Powers(clone)) + notify(player, "Warning: @CLONE/PRESERVE on an exit with WIZ, ROY, @Powers, or Warnings."); notify(player, "Exit cloned."); #ifdef LOCAL_DATA LocData(clone) = NULL; local_data_clone(clone, thing); #endif diff -u5 ../testmush/src/destroy.c src/destroy.c --- ../testmush/src/destroy.c Fri Apr 2 10:54:55 1999 +++ src/destroy.c Wed Apr 7 14:34:25 1999 @@ -786,11 +786,11 @@ /* Deal with objects owned by the player. */ for (i = 0; i < db_top; i++) { if (Owner(i) == thing && i != thing) { if (DESTROY_POSSESSIONS ? (REALLY_SAFE ? Safe(i) : 0) : 1) { - chown_object(GOD, i, GOD); + chown_object(GOD, i, GOD, 0); } else { free_object(i); } } } diff -u5 ../testmush/src/fundb.c src/fundb.c --- ../testmush/src/fundb.c Fri Apr 2 10:55:00 1999 +++ src/fundb.c Wed Apr 7 14:35:03 1999 @@ -1417,11 +1417,11 @@ { if (!command_check_byname(executor, "@clone")) { safe_str("#-1 PERMISSION DENIED", buff, bp); return; } - safe_str(unparse_dbref(do_clone(executor, args[0])), buff, bp); + safe_str(unparse_dbref(do_clone(executor, args[0], 0)), buff, bp); } /* -------------------------------------------------------------------------- * Attribute functions: LINK, SET diff -u5 ../testmush/src/set.c src/set.c --- ../testmush/src/set.c Fri Apr 2 10:55:22 1999 +++ src/set.c Wed Apr 7 14:44:17 1999 @@ -39,13 +39,13 @@ extern void delete_player _((dbref player, char *alias)); extern void add_player _((dbref player, char *alias)); extern void charge_action _((dbref player, dbref thing, const char *awhat)); void do_name _((dbref player, const char *name, char *newname)); -void do_chown _((dbref player, const char *name, const char *newobj)); +void do_chown _((dbref player, const char *name, const char *newobj, int preserve)); static int chown_ok _((dbref player, dbref thing, dbref newowner)); -void chown_object _((dbref player, dbref thing, dbref newowner)); +void chown_object _((dbref player, dbref thing, dbref newowner, int preserve)); void do_chzone _((dbref player, const char *name, const char *newobj)); void do_attrib_flags _((dbref player, const char *obj, const char *atrname, const char *flag)); int do_set _((dbref player, const char *name, char *flag)); void do_cpattr _((dbref player, char *oldpair, char **newpair, int move)); void do_gedit _((dbref player, char *it, char **argv)); @@ -166,14 +166,15 @@ notify(player, "Name set."); } } void -do_chown(player, name, newobj) +do_chown(player, name, newobj, preserve) dbref player; const char *name; const char *newobj; + int preserve; { dbref thing; dbref newowner = NOTHING; char *sp; long match_flags = MAT_POSSESSION | MAT_HERE | MAT_EXIT; @@ -209,20 +210,24 @@ /* Permissions checking */ if (!chown_ok(player, thing, newowner)) { notify(player, "Permission denied."); return; } + if (preserve && !Wizard(player)) { + notify(player, "You cannot @CHOWN/PRESERVE. Use normal @CHOWN."); + return; + } /* chowns to the zone master don't count towards fees */ if (!ZMaster(newowner)) { if (!can_pay_fees(player, OBJECT_DEPOSIT(Pennies(thing)))) /* not enough money or quota */ return; giveto(Owner(thing), OBJECT_DEPOSIT(Pennies(thing))); #ifdef QUOTA change_quota(Owner(thing), QUOTA_COST); #endif } - chown_object(player, thing, newowner); + chown_object(player, thing, newowner, preserve); notify(player, "Owner changed."); } static int chown_ok(player, thing, newowner) @@ -274,31 +279,45 @@ } /* Actually change the ownership of something, and fix bits */ void -chown_object(player, thing, newowner) +chown_object(player, thing, newowner, preserve) dbref player; dbref thing; dbref newowner; + int preserve; { undestroy(player, thing); if (God(player)) { Owner(thing) = newowner; } else { Owner(thing) = Owner(newowner); } Zone(thing) = Zone(newowner); Flags(thing) &= ~CHOWN_OK; - Flags(thing) &= ~WIZARD; + if (!preserve || !Wizard(player)) { + Flags(thing) &= ~WIZARD; #ifdef ROYALTY_FLAG - Flags(thing) &= ~ROYALTY; + Flags(thing) &= ~ROYALTY; #endif - Flags(thing) &= ~INHERIT; - Flags(thing) |= HALT; - Powers(thing) = 0; /* wipe out all powers */ - do_halt(thing, "", thing); + Flags(thing) &= ~INHERIT; + Flags(thing) |= HALT; + Powers(thing) = 0; /* wipe out all powers */ + do_halt(thing, "", thing); + } else { + if ((newowner != player) && Wizard(thing) && !God(player)) { + notify(player, "Warning: WIZ flag reset because @CHOWN/PRESERVE is to a third party."); + Flags(thing) &= ~WIZARD; + } + if (Powers(thing) || Wizard(thing) || +#ifdef ROYALTY_FLAG + Royalty(thing) || +#endif + Inherit(thing)) + notify(player, "Warning: @CHOWN/PRESERVE on a target with WIZ, ROY, INHERIT, or @power priveleges."); + } } void do_chzone(player, name, newobj) --- ../testmush/game/txt/hlp/penncmd.hlp Fri Apr 2 10:56:11 1999 +++ game/txt/hlp/penncmd.hlp Fri Apr 9 09:24:47 1999 @@ -392,17 +392,22 @@ object is used, and once it reaches zero, the object cannot be used anymore. See also: use, @runout & @chown - @chown = + @chown [= ] + @chown/preserve [= ] - Changes the ownership of to . You can chown things, - rooms, or exits. To chown a thing, you have to be carrying it. - If you do not own an object, you can only chown it if it is CHOWN_OK. + Changes the ownership of to yourself or to . You can + chown things, rooms, or exits. To chown a thing, you have to be carrying + it. If you do not own an object, you can only chown it if it is CHOWN_OK. If you're not a Wizard, you can only @chown objects to yourself or to a Zone Master whose zone-lock you pass. + If you are a Wizard, you may also use @chown/preserve. This preserves + all bitsand powers that you have the authority to set, and also does not + halt the object. But beware, chowning an active object that has @waits, + semaphores, or @trigger loops may have odd effects. Examples: (for a room) @chown here=me (for an object) @chown box=Soundwave @@ -462,18 +467,23 @@ may use this command. See also: @chzone, ZONES & @clone @clone + @clone/preserve + For objects, creates an exact duplicate of it and puts it in the current room. For exits, it creates an exact duplicate of that exit, except the clone's source is the current room rather than whatever the original exit's source was. If creation times are enabled, a clone will have a different creation time than the object it was cloned from, but will have the same modification time, to make tracking revisions of code easier. + + A wizard may use @clone/preserve, which has the effect of preserving + all the bits, powers, and warnings of the original object. See also: @create & @command @command @command/