00001
00002
00003
00004
00005
00006 #include "copyright.h"
00007 #include "autoconf.h"
00008 #include "config.h"
00009 #include "externs.h"
00010
00011 #include "attrs.h"
00012 #include "command.h"
00013 #include "powers.h"
00014
00015
00016
00017
00018 static dbref parse_linkable_room(dbref player, char *room_name)
00019 {
00020 init_match(player, room_name, NOTYPE);
00021 match_everything(MAT_NO_EXITS | MAT_NUMERIC | MAT_HOME);
00022 dbref room = match_result();
00023
00024
00025
00026 if (room == HOME)
00027 {
00028 return HOME;
00029 }
00030
00031
00032
00033 if (!Good_obj(room))
00034 {
00035 notify_quiet(player, "That's not a valid object.");
00036 return NOTHING;
00037 }
00038 else if ( !Has_contents(room)
00039 || !Linkable(player, room))
00040 {
00041 notify_quiet(player, "You can't link to that.");
00042 return NOTHING;
00043 }
00044 else
00045 {
00046 return room;
00047 }
00048 }
00049
00050
00051
00052
00053 static void open_exit(dbref player, dbref loc, char *direction, char *linkto)
00054 {
00055 if (!Good_obj(loc))
00056 {
00057 return;
00058 }
00059 if (!direction || !*direction)
00060 {
00061 notify_quiet(player, "Open where?");
00062 return;
00063 }
00064 else if (!Controls(player, loc))
00065 {
00066 if(!(Open_ok(loc) && could_doit(player, loc, A_LOPEN)))
00067 {
00068 notify_quiet(player, NOPERM_MESSAGE);
00069 return;
00070 }
00071 }
00072 dbref exit = create_obj(player, TYPE_EXIT, direction, 0);
00073 if (exit == NOTHING)
00074 {
00075 return;
00076 }
00077
00078
00079
00080 s_Exits(exit, loc);
00081 s_Next(exit, Exits(loc));
00082 s_Exits(loc, exit);
00083 local_data_create(exit);
00084
00085
00086
00087 notify_quiet(player, "Opened.");
00088
00089
00090
00091 if (!linkto || !*linkto)
00092 {
00093 return;
00094 }
00095
00096 loc = parse_linkable_room(player, linkto);
00097 if (Good_obj(loc) || loc == HOME)
00098 {
00099
00100
00101 if (!could_doit(player, loc, A_LLINK))
00102 {
00103 notify_quiet(player, "You can't link to there.");
00104 return;
00105 }
00106
00107
00108
00109 if (!payfor(player, mudconf.linkcost))
00110 {
00111 notify_quiet(player,
00112 tprintf("You don't have enough %s to link.",
00113 mudconf.many_coins));
00114 }
00115 else
00116 {
00117 s_Location(exit, loc);
00118 notify_quiet(player, "Linked.");
00119 }
00120 }
00121 }
00122
00123 void do_open(dbref executor, dbref caller, dbref enactor, int key,
00124 char *direction, char *links[], int nlinks)
00125 {
00126 UNUSED_PARAMETER(caller);
00127 UNUSED_PARAMETER(enactor);
00128
00129 char *dest;
00130
00131
00132
00133 if (nlinks >= 1)
00134 {
00135 dest = links[0];
00136 }
00137 else
00138 {
00139 dest = NULL;
00140 }
00141
00142 dbref loc;
00143 if (key == OPEN_INVENTORY)
00144 {
00145 loc = executor;
00146 }
00147 else
00148 {
00149 loc = Location(executor);
00150 }
00151
00152 open_exit(executor, loc, direction, dest);
00153
00154
00155
00156 if (nlinks >= 2)
00157 {
00158 dbref destnum = parse_linkable_room(executor, dest);
00159 if (Good_obj(destnum) || destnum == HOME)
00160 {
00161 char buff[12];
00162 mux_ltoa(loc, buff);
00163 open_exit(executor, destnum, links[1], buff);
00164 }
00165 }
00166 }
00167
00168
00169
00170
00171
00172 static void link_exit(dbref player, dbref exit, dbref dest)
00173 {
00174
00175
00176 if ( dest != HOME
00177 && ( ( !Controls(player, dest)
00178 && !Link_ok(dest))
00179 || !could_doit(player, dest, A_LLINK)))
00180 {
00181 notify_quiet(player, NOPERM_MESSAGE);
00182 return;
00183 }
00184
00185
00186
00187 if ( Location(exit) != NOTHING
00188 && !Controls(player, exit))
00189 {
00190 notify_quiet(player, NOPERM_MESSAGE);
00191 return;
00192 }
00193
00194
00195
00196 int cost = mudconf.linkcost;
00197 int quot = 0;
00198 if (Owner(exit) != Owner(player))
00199 {
00200 cost += mudconf.opencost;
00201 quot += mudconf.exit_quota;
00202 }
00203 if (!canpayfees(player, player, cost, quot))
00204 {
00205 return;
00206 }
00207
00208
00209
00210 if (Owner(exit) != Owner(player))
00211 {
00212 giveto(Owner(exit), mudconf.opencost);
00213 add_quota(Owner(exit), quot);
00214 s_Owner(exit, Owner(player));
00215 db[exit].fs.word[FLAG_WORD1] &= ~(INHERIT | WIZARD);
00216 db[exit].fs.word[FLAG_WORD1] |= HALT;
00217 }
00218
00219
00220
00221 s_Location(exit, dest);
00222 if (!Quiet(player))
00223 {
00224 notify_quiet(player, "Linked.");
00225 }
00226 }
00227
00228 void do_link
00229 (
00230 dbref executor,
00231 dbref caller,
00232 dbref enactor,
00233 int key,
00234 int nargs,
00235 char *what,
00236 char *where
00237 )
00238 {
00239 UNUSED_PARAMETER(nargs);
00240
00241
00242
00243 init_match(executor, what, TYPE_EXIT);
00244 match_everything(0);
00245 dbref thing = noisy_match_result();
00246 if (thing == NOTHING)
00247 {
00248 return;
00249 }
00250
00251
00252
00253 if (!where || !*where)
00254 {
00255 do_unlink(executor, caller, enactor, key, what);
00256 return;
00257 }
00258
00259 dbref room;
00260 char *buff;
00261
00262 switch (Typeof(thing))
00263 {
00264 case TYPE_EXIT:
00265
00266
00267
00268 room = parse_linkable_room(executor, where);
00269 if (Good_obj(room) || room == HOME)
00270 {
00271 link_exit(executor, thing, room);
00272 }
00273 break;
00274
00275 case TYPE_PLAYER:
00276 case TYPE_THING:
00277
00278
00279
00280 if (!Controls(executor, thing))
00281 {
00282 notify_quiet(executor, NOPERM_MESSAGE);
00283 break;
00284 }
00285 init_match(executor, where, NOTYPE);
00286 match_everything(MAT_NO_EXITS);
00287 room = noisy_match_result();
00288 if (!Good_obj(room))
00289 {
00290 break;
00291 }
00292 if (!Has_contents(room))
00293 {
00294 notify_quiet(executor, "Can't link to an exit.");
00295 break;
00296 }
00297 if ( !can_set_home(executor, thing, room)
00298 || !could_doit(executor, room, A_LLINK))
00299 {
00300 notify_quiet(executor, NOPERM_MESSAGE);
00301 }
00302 else if (room == HOME)
00303 {
00304 notify_quiet(executor, "Can't set home to home.");
00305 }
00306 else
00307 {
00308 dbref nHomeOrig = Home(thing);
00309 dbref nHomeNew = room;
00310 s_Home(thing, nHomeNew);
00311 if (!Quiet(executor))
00312 {
00313 char *buff1 = alloc_lbuf("do_link.notify");
00314 char *bp = buff1;
00315
00316 char *p;
00317 p = tprintf("Home of %s(#%d) changed from ", Name(thing), thing);
00318 safe_str(p, buff1, &bp);
00319 p = tprintf("%s(#%d) to ", Name(nHomeOrig), nHomeOrig);
00320 safe_str(p, buff1, &bp);
00321 p = tprintf("%s(#%d).", Name(nHomeNew), nHomeNew);
00322 safe_str(p, buff1, &bp);
00323 *bp = '\0';
00324 notify_quiet(executor, buff1);
00325 free_lbuf(buff1);
00326 }
00327 }
00328 break;
00329
00330 case TYPE_ROOM:
00331
00332
00333
00334 if (!Controls(executor, thing))
00335 {
00336 notify_quiet(executor, NOPERM_MESSAGE);
00337 break;
00338 }
00339 room = parse_linkable_room(executor, where);
00340 if ( !Good_obj(room)
00341 && room != HOME)
00342 {
00343 break;
00344 }
00345
00346 if ( room != HOME
00347 && !isRoom(room))
00348 {
00349 notify_quiet(executor, "That is not a room!");
00350 }
00351 else if ( room != HOME
00352 && ( ( !Controls(executor, room)
00353 && !Link_ok(room))
00354 || !could_doit(executor, room, A_LLINK)))
00355 {
00356 notify_quiet(executor, NOPERM_MESSAGE);
00357 }
00358 else
00359 {
00360 dbref nDroptoOrig = Dropto(thing);
00361 dbref nDroptoNew = room;
00362 s_Dropto(thing, room);
00363 if (!Quiet(executor))
00364 {
00365 char *buff1 = alloc_lbuf("do_link2.notify");
00366 char *bp = buff1;
00367
00368 char *p;
00369 p = tprintf("Dropto of %s(#%d) changed from ", Name(thing), thing);
00370 safe_str(p, buff1, &bp);
00371 p = tprintf("%s(#%d) to ", Name(nDroptoOrig), nDroptoOrig);
00372 safe_str(p, buff1, &bp);
00373 p = tprintf("%s(#%d).", Name(nDroptoNew), nDroptoNew);
00374 safe_str(p, buff1, &bp);
00375 *bp = '\0';
00376 notify_quiet(executor, buff1);
00377 free_lbuf(buff1);
00378 }
00379 }
00380 break;
00381
00382 case TYPE_GARBAGE:
00383
00384 notify_quiet(executor, NOPERM_MESSAGE);
00385 break;
00386
00387 default:
00388
00389 STARTLOG(LOG_BUGS, "BUG", "OTYPE");
00390 buff = alloc_mbuf("do_link.LOG.badtype");
00391 sprintf(buff, "Strange object type: object #%d = %d",
00392 thing, Typeof(thing));
00393 log_text(buff);
00394 free_mbuf(buff);
00395 ENDLOG;
00396 }
00397 }
00398
00399
00400
00401
00402 void do_parent
00403 (
00404 dbref executor,
00405 dbref caller,
00406 dbref enactor,
00407 int key,
00408 int nargs,
00409 char *tname,
00410 char *pname
00411 )
00412 {
00413 UNUSED_PARAMETER(caller);
00414 UNUSED_PARAMETER(enactor);
00415 UNUSED_PARAMETER(key);
00416 UNUSED_PARAMETER(nargs);
00417
00418 dbref thing, parent, curr;
00419 int lev;
00420
00421
00422
00423 init_match(executor, tname, NOTYPE);
00424 match_everything(0);
00425 thing = noisy_match_result();
00426 if (!Good_obj(thing))
00427 {
00428 return;
00429 }
00430
00431
00432
00433 if ( Going(thing)
00434 || !Controls(executor, thing))
00435 {
00436 notify_quiet(executor, NOPERM_MESSAGE);
00437 return;
00438 }
00439
00440
00441
00442 if (*pname)
00443 {
00444 init_match(executor, pname, Typeof(thing));
00445 match_everything(0);
00446 parent = noisy_match_result();
00447 if (!Good_obj(parent))
00448 {
00449 return;
00450 }
00451
00452
00453
00454 if (!Parentable(executor, parent))
00455 {
00456 notify_quiet(executor, NOPERM_MESSAGE);
00457 return;
00458 }
00459
00460
00461
00462 ITER_PARENTS(parent, curr, lev)
00463 {
00464 if (curr == thing)
00465 {
00466 notify_quiet(executor, "You can't have yourself as a parent!");
00467 return;
00468 }
00469 }
00470 }
00471 else
00472 {
00473 parent = NOTHING;
00474 }
00475
00476 s_Parent(thing, parent);
00477 if (!Quiet(thing) && !Quiet(executor))
00478 {
00479 if (parent == NOTHING)
00480 notify_quiet(executor, "Parent cleared.");
00481 else
00482 notify_quiet(executor, "Parent set.");
00483 }
00484 }
00485
00486
00487
00488
00489 void do_dig(dbref executor, dbref caller, dbref enactor, int key, char *name,
00490 char *args[], int nargs)
00491 {
00492 UNUSED_PARAMETER(caller);
00493
00494
00495
00496 if (!name || !*name)
00497 {
00498 notify_quiet(executor, "Dig what?");
00499 return;
00500 }
00501 dbref room = create_obj(executor, TYPE_ROOM, name, 0);
00502 if (room == NOTHING)
00503 {
00504 return;
00505 }
00506
00507 local_data_create(room);
00508 notify(executor, tprintf("%s created as room #%d.", name, room));
00509
00510 char *buff = alloc_sbuf("do_dig");
00511 if ( nargs >= 1
00512 && args[0]
00513 && *args[0])
00514 {
00515 mux_ltoa(room, buff);
00516 open_exit(executor, Location(executor), args[0], buff);
00517 }
00518 if ( nargs >= 2
00519 && args[1]
00520 && *args[1])
00521 {
00522 mux_ltoa(Location(executor), buff);
00523 open_exit(executor, room, args[1], buff);
00524 }
00525 free_sbuf(buff);
00526 if (key == DIG_TELEPORT)
00527 {
00528 (void)move_via_teleport(executor, room, enactor, 0);
00529 }
00530 }
00531
00532
00533
00534
00535 void do_create
00536 (
00537 dbref executor,
00538 dbref caller,
00539 dbref enactor,
00540 int key,
00541 int nargs,
00542 char *name,
00543 char *coststr
00544 )
00545 {
00546 UNUSED_PARAMETER(caller);
00547 UNUSED_PARAMETER(enactor);
00548 UNUSED_PARAMETER(key);
00549
00550 int cost = 0;
00551 if (!name || !*name)
00552 {
00553 notify_quiet(executor, "Create what?");
00554 return;
00555 }
00556 else if ( nargs == 2
00557 && (cost = mux_atol(coststr)) < 0)
00558 {
00559 notify_quiet(executor, "You can't create an object for less than nothing!");
00560 return;
00561 }
00562 dbref thing = create_obj(executor, TYPE_THING, name, cost);
00563 if (thing == NOTHING)
00564 {
00565 return;
00566 }
00567
00568 move_via_generic(thing, executor, NOTHING, 0);
00569 s_Home(thing, new_home(executor));
00570 if (!Quiet(executor))
00571 {
00572 notify(executor, tprintf("%s created as object #%d", Name(thing), thing));
00573 }
00574
00575 local_data_create(thing);
00576 }
00577
00578
00579
00580
00581
00582 void do_clone
00583 (
00584 dbref executor,
00585 dbref caller,
00586 dbref enactor,
00587 int key,
00588 int nargs,
00589 char *name,
00590 char *arg2
00591 )
00592 {
00593 UNUSED_PARAMETER(caller);
00594 UNUSED_PARAMETER(enactor);
00595 UNUSED_PARAMETER(nargs);
00596
00597 dbref clone, thing, new_owner, loc;
00598 FLAG rmv_flags;
00599 int cost;
00600
00601 if ((key & CLONE_INVENTORY) || !Has_location(executor))
00602 loc = executor;
00603 else
00604 loc = Location(executor);
00605
00606 if (!Good_obj(loc))
00607 return;
00608
00609 init_match(executor, name, NOTYPE);
00610 match_everything(0);
00611 thing = noisy_match_result();
00612 if ((thing == NOTHING) || (thing == AMBIGUOUS))
00613 {
00614 return;
00615 }
00616
00617
00618
00619
00620 if (!Examinable(executor, thing))
00621 {
00622 notify_quiet(executor, NOPERM_MESSAGE);
00623 return;
00624 }
00625 if (isPlayer(thing))
00626 {
00627 notify_quiet(executor, "You cannot clone players!");
00628 return;
00629 }
00630
00631
00632
00633 if ( !Controls(executor, thing)
00634 && !Parent_ok(thing)
00635 && (key & CLONE_FROM_PARENT))
00636 {
00637 notify_quiet(executor,
00638 tprintf("You don't control %s, ignoring /parent.",
00639 Name(thing)));
00640 key &= ~CLONE_FROM_PARENT;
00641 }
00642
00643
00644
00645 new_owner = (key & CLONE_PRESERVE) ? Owner(thing) : Owner(executor);
00646 if (key & CLONE_SET_COST)
00647 {
00648 cost = mux_atol(arg2);
00649 if (cost < mudconf.createmin)
00650 cost = mudconf.createmin;
00651 if (cost > mudconf.createmax)
00652 cost = mudconf.createmax;
00653 arg2 = NULL;
00654 }
00655 else
00656 {
00657 cost = 1;
00658 switch (Typeof(thing))
00659 {
00660 case TYPE_THING:
00661 cost = OBJECT_DEPOSIT((mudconf.clone_copy_cost) ?
00662 Pennies(thing) : 1);
00663 break;
00664 case TYPE_ROOM:
00665 cost = mudconf.digcost;
00666 break;
00667 case TYPE_EXIT:
00668
00669 if (!Controls(executor, loc))
00670 {
00671 notify_quiet(executor, NOPERM_MESSAGE);
00672 return;
00673 }
00674 cost = mudconf.digcost;
00675 break;
00676 }
00677 }
00678
00679
00680
00681 bool bValid;
00682 int nValidName;
00683 char *pValidName = MakeCanonicalObjectName(arg2, &nValidName, &bValid);
00684 const char *clone_name;
00685 if (bValid)
00686 {
00687 clone_name = pValidName;
00688 }
00689 else
00690 {
00691 clone_name = Name(thing);
00692 }
00693 clone = create_obj(new_owner, Typeof(thing), clone_name, cost);
00694
00695 if (clone == NOTHING)
00696 {
00697 return;
00698 }
00699
00700
00701
00702 if (key & CLONE_FROM_PARENT)
00703 {
00704 s_Parent(clone, thing);
00705 }
00706 else
00707 {
00708 atr_cpy(clone, thing, false);
00709 }
00710
00711
00712
00713 s_Name(clone, clone_name);
00714
00715
00716
00717 s_Pennies(clone, OBJECT_ENDOWMENT(cost));
00718
00719
00720
00721 rmv_flags = WIZARD;
00722 if (!(key & CLONE_INHERIT) || !Inherits(executor))
00723 {
00724 rmv_flags |= INHERIT | IMMORTAL;
00725 }
00726 s_Flags(clone, FLAG_WORD1, Flags(thing) & ~rmv_flags);
00727
00728
00729
00730 if (!Quiet(executor))
00731 {
00732 if (arg2 && *arg2)
00733 {
00734 notify(executor,
00735 tprintf("%s cloned as %s, new copy is object #%d.",
00736 Name(thing), arg2, clone));
00737 }
00738 else
00739 {
00740 notify(executor,
00741 tprintf("%s cloned, new copy is object #%d.",
00742 Name(thing), clone));
00743 }
00744 }
00745
00746
00747
00748
00749 switch (Typeof(thing))
00750 {
00751 case TYPE_THING:
00752
00753 s_Home(clone, clone_home(executor, thing));
00754 move_via_generic(clone, loc, executor, 0);
00755 break;
00756
00757 case TYPE_ROOM:
00758
00759 s_Dropto(clone, NOTHING);
00760 if (Dropto(thing) != NOTHING)
00761 {
00762 link_exit(executor, clone, Dropto(thing));
00763 }
00764 break;
00765
00766 case TYPE_EXIT:
00767
00768 s_Exits(loc, insert_first(Exits(loc), clone));
00769 s_Exits(clone, loc);
00770 s_Location(clone, NOTHING);
00771 if (Location(thing) != NOTHING)
00772 {
00773 link_exit(executor, clone, Location(thing));
00774 }
00775 break;
00776 }
00777
00778
00779
00780 if (new_owner == Owner(thing))
00781 {
00782 if (!(key & CLONE_FROM_PARENT))
00783 {
00784 s_Parent(clone, Parent(thing));
00785 }
00786 did_it(executor, clone, 0, NULL, 0, NULL, A_ACLONE,
00787 (char **)NULL, 0);
00788 }
00789 else
00790 {
00791 if ( !(key & CLONE_FROM_PARENT)
00792 && (Controls(executor, thing) || Parent_ok(thing)))
00793 {
00794 s_Parent(clone, Parent(thing));
00795 }
00796 s_Halted(clone);
00797 }
00798
00799 local_data_clone(clone, thing);
00800 }
00801
00802
00803
00804
00805 void do_pcreate
00806 (
00807 dbref executor,
00808 dbref caller,
00809 dbref enactor,
00810 int key,
00811 int nargs,
00812 char *name,
00813 char *pass
00814 )
00815 {
00816 UNUSED_PARAMETER(caller);
00817 UNUSED_PARAMETER(enactor);
00818 UNUSED_PARAMETER(nargs);
00819
00820 const char *pmsg;
00821 bool isrobot = (key == PCRE_ROBOT);
00822 dbref newplayer = create_player(name, pass, executor, isrobot, &pmsg);
00823 if (newplayer == NOTHING)
00824 {
00825 notify_quiet(executor, tprintf("Failure creating '%s'. %s", name, pmsg));
00826 return;
00827 }
00828 AddToPublicChannel(newplayer);
00829 if (isrobot)
00830 {
00831 move_object(newplayer, Location(executor));
00832 notify_quiet(executor,
00833 tprintf("New robot '%s' (#%d) created with password '%s'",
00834 name, newplayer, pass));
00835 notify_quiet(executor, "Your robot has arrived.");
00836 STARTLOG(LOG_PCREATES, "CRE", "ROBOT");
00837 log_name(newplayer);
00838 log_text(" created by ");
00839 log_name(executor);
00840 ENDLOG;
00841 }
00842 else
00843 {
00844 move_object(newplayer, mudconf.start_room);
00845 notify_quiet(executor,
00846 tprintf("New player '%s' (#%d) created with password '%s'",
00847 name, newplayer, pass));
00848 STARTLOG(LOG_PCREATES | LOG_WIZARD, "WIZ", "PCREA");
00849 log_name(newplayer);
00850 log_text(" created by ");
00851 log_name(executor);
00852 ENDLOG;
00853 #ifdef GAME_DOOFERMUX
00854
00855
00856 atr_add_raw(newplayer, A_REGINFO, "*Requires Registration*");
00857 #endif
00858 }
00859 }
00860
00861
00862
00863
00864
00865 static bool destroyable(dbref victim)
00866 {
00867 if ( (victim == mudconf.default_home)
00868 || (victim == mudconf.start_home)
00869 || (victim == mudconf.start_room)
00870 || (victim == mudconf.master_room)
00871 || (victim == (dbref) 0)
00872 || (God(victim)))
00873 {
00874 return false;
00875 }
00876 return true;
00877 }
00878
00879
00880
00881
00882 static bool can_destroy_player(dbref player, dbref victim)
00883 {
00884 if (!Wizard(player))
00885 {
00886 notify_quiet(player, "Sorry, no suicide allowed.");
00887 return false;
00888 }
00889 if (Wizard(victim))
00890 {
00891 notify_quiet(player, "Even you can't do that!");
00892 return false;
00893 }
00894 return true;
00895 }
00896
00897 void do_destroy(dbref executor, dbref caller, dbref enactor, int key, char *what)
00898 {
00899 UNUSED_PARAMETER(caller);
00900 UNUSED_PARAMETER(enactor);
00901
00902
00903
00904 dbref thing = match_controlled_quiet(executor, what);
00905
00906
00907
00908 if ( thing == NOTHING
00909 && Controls(executor, Location(executor)))
00910 {
00911 init_match(executor, what, TYPE_EXIT);
00912 match_exit();
00913 thing = last_match_result();
00914 }
00915
00916
00917
00918 if (thing == NOTHING)
00919 {
00920 init_match(executor, what, TYPE_THING);
00921 match_possession();
00922 thing = last_match_result();
00923 if ( thing != NOTHING
00924 && !(isThing(thing) && Destroy_ok(thing)))
00925 {
00926 thing = NOPERM;
00927 }
00928 }
00929
00930
00931
00932 if (match_status(executor, thing) == NOTHING)
00933 {
00934 return;
00935 }
00936
00937
00938
00939 if ( Safe(thing, executor)
00940 && !(key & DEST_OVERRIDE)
00941 && !(isThing(thing) && Destroy_ok(thing)))
00942 {
00943 notify_quiet(executor, "Sorry, that object is protected. Use @destroy/override to destroy it.");
00944 return;
00945 }
00946
00947
00948
00949 if (!destroyable(thing))
00950 {
00951 notify_quiet(executor, "You can't destroy that!");
00952 return;
00953 }
00954
00955
00956
00957 if( isPlayer(thing)
00958 && !can_destroy_player(executor, thing))
00959 {
00960 return;
00961 }
00962
00963 char *NameOfType = alloc_sbuf("do_destroy.NameOfType");
00964 strcpy(NameOfType, object_types[Typeof(thing)].name);
00965 mux_strlwr(NameOfType);
00966 if (Going(thing))
00967 {
00968 if (!mudconf.destroy_going_now)
00969 {
00970 notify_quiet(executor, tprintf("No sense beating a dead %s.", NameOfType));
00971 free_sbuf(NameOfType);
00972 return;
00973 }
00974 key |= DEST_INSTANT;
00975 }
00976
00977
00978
00979 dbref ThingOwner = Owner(thing);
00980 bool bInstant = (key & DEST_INSTANT) || Destroy_ok(thing) || Destroy_ok(ThingOwner);
00981
00982 if (!bInstant)
00983 {
00984
00985
00986 switch (Typeof(thing))
00987 {
00988 case TYPE_ROOM:
00989 notify_all(thing, executor, "The room shakes and begins to crumble.");
00990 break;
00991
00992 case TYPE_PLAYER:
00993 atr_add_raw(thing, A_DESTROYER, mux_ltoa_t(executor));
00994 if (!atr_get_raw(thing, A_DESTROYER))
00995 {
00996
00997
00998
00999
01000 bInstant = true;
01001 notify(executor, "Player has a lot of attributes. Performing destruction immediately.");
01002 break;
01003 }
01004
01005
01006
01007 case TYPE_EXIT:
01008 case TYPE_THING:
01009 notify(executor, tprintf("The %s shakes and begins to crumble.",
01010 NameOfType));
01011 break;
01012
01013 default:
01014 notify(executor, "Weird object type cannot be destroyed.");
01015 free_sbuf(NameOfType);
01016 return;
01017 }
01018
01019 if ( !bInstant
01020 && !Quiet(thing)
01021 && !Quiet(ThingOwner))
01022 {
01023 notify_quiet(ThingOwner,
01024 tprintf("You will be rewarded shortly for %s(#%d).",
01025 Moniker(thing), thing));
01026 }
01027 }
01028 free_sbuf(NameOfType);
01029
01030
01031
01032 if (!Quiet(executor))
01033 {
01034 if (Good_owner(ThingOwner))
01035 {
01036 if (ThingOwner == Owner(executor))
01037 {
01038 if (!Quiet(thing))
01039 {
01040 notify(executor, tprintf("Destroyed %s(#%d).",
01041 Moniker(thing), thing));
01042 }
01043 }
01044 else if (ThingOwner == thing)
01045 {
01046 notify(executor, tprintf("Destroyed %s(#%d).",
01047 Moniker(thing), thing));
01048 }
01049 else
01050 {
01051 char *tname = alloc_lbuf("destroy_obj");
01052 strcpy(tname, Moniker(ThingOwner));
01053 notify(executor, tprintf("Destroyed %s's %s(#%d).",
01054 tname, Moniker(thing), thing));
01055 free_lbuf(tname);
01056 }
01057 }
01058 }
01059
01060 if (bInstant)
01061 {
01062
01063
01064 switch (Typeof(thing))
01065 {
01066 case TYPE_EXIT:
01067 destroy_exit(thing);
01068 break;
01069
01070 case TYPE_PLAYER:
01071 destroy_player(executor, thing);
01072 break;
01073
01074 case TYPE_ROOM:
01075 empty_obj(thing);
01076 destroy_obj(thing);
01077 break;
01078
01079 case TYPE_THING:
01080 destroy_thing(thing);
01081 break;
01082
01083 default:
01084 notify(executor, "Weird object type cannot be destroyed.");
01085 return;
01086 }
01087 }
01088 s_Going(thing);
01089 }