00001
00002
00003
00004
00005 #include "copyright.h"
00006 #include "config.h"
00007
00008 #include "mudconf.h"
00009 #include "config.h"
00010 #include "db.h"
00011 #include "interface.h"
00012 #include "match.h"
00013 #include "attrs.h"
00014 #include "externs.h"
00015 #include "powers.h"
00016
00017
00018
00019
00020
00021
00022
00023 static void process_leave_loc(dbref thing, dbref dest, dbref cause,
00024 int canhear, int hush)
00025 {
00026 dbref loc;
00027 int quiet, pattr, oattr, aattr;
00028
00029 loc = Location(thing);
00030 if((loc == NOTHING) || (loc == dest))
00031 return;
00032
00033 if(dest == HOME)
00034 dest = Home(thing);
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 quiet = (!(Wizard(loc) || (!Dark(thing) && !Dark(loc)) || (canhear &&
00046 !(Wizard(thing)
00047 &&
00048 Dark
00049 (thing)))))
00050 || (hush & HUSH_LEAVE);
00051 oattr = quiet ? 0 : A_OLEAVE;
00052 aattr = quiet ? 0 : A_ALEAVE;
00053 pattr = (!mudconf.terse_movemsg && Terse(thing)) ? 0 : A_LEAVE;
00054 did_it(thing, loc, pattr, NULL, oattr, NULL, aattr, (char **) NULL, 0);
00055
00056
00057
00058
00059
00060 if((dest != NOTHING) && !quiet)
00061 did_it(thing, dest, 0, NULL, A_OXENTER, NULL, 0, (char **) NULL, 0);
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 if(!quiet)
00072 if((!Dark(thing) && !Dark(loc)) || (canhear && !(Wizard(thing) &&
00073 Dark(thing)))) {
00074 notify_except2(loc, thing, thing, cause,
00075 tprintf("%s has left.", Name(thing)));
00076 }
00077 }
00078
00079
00080
00081
00082
00083
00084 static void process_enter_loc(dbref thing, dbref src, dbref cause,
00085 int canhear, int hush)
00086 {
00087 dbref loc;
00088 int quiet, pattr, oattr, aattr;
00089
00090 loc = Location(thing);
00091 if((loc == NOTHING) || (loc == src))
00092 return;
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 quiet = (!(Wizard(loc) || (!Dark(thing) && !Dark(loc)) || (canhear &&
00104 !(Wizard(thing)
00105 &&
00106 Dark
00107 (thing)))))
00108 || (hush & HUSH_ENTER);
00109 oattr = quiet ? 0 : A_OENTER;
00110 aattr = quiet ? 0 : A_AENTER;
00111 pattr = (!mudconf.terse_movemsg && Terse(thing)) ? 0 : A_ENTER;
00112 did_it(thing, loc, pattr, NULL, oattr, NULL, aattr, (char **) NULL, 0);
00113
00114
00115
00116
00117
00118 if((src != NOTHING) && !quiet)
00119 did_it(thing, src, 0, NULL, A_OXLEAVE, NULL, 0, (char **) NULL, 0);
00120
00121
00122
00123
00124
00125
00126
00127 if(!quiet && canhear && !(Dark(thing) && Wizard(thing))) {
00128 notify_except2(loc, thing, thing, cause, tprintf("%s has arrived.",
00129 Name(thing)));
00130 }
00131 }
00132
00133
00134
00135
00136
00137
00138
00139 void move_object(dbref thing, dbref dest)
00140 {
00141 dbref src;
00142
00143
00144
00145
00146
00147 src = Location(thing);
00148 if(src != NOTHING)
00149 s_Contents(src, remove_first(Contents(src), thing));
00150
00151
00152
00153
00154
00155 if(dest == HOME)
00156 dest = Home(thing);
00157
00158
00159
00160
00161
00162 if(dest != NOTHING)
00163 s_Contents(dest, insert_first(Contents(dest), thing));
00164 else
00165 s_Next(thing, NOTHING);
00166 s_Location(thing, dest);
00167
00168
00169
00170
00171
00172 look_in(thing, dest, (LK_SHOWEXIT | LK_OBEYTERSE));
00173 if(isPlayer(thing) && (mudconf.payfind > 0) &&
00174 (Pennies(thing) < mudconf.paylimit) && (!Controls(thing, dest)) &&
00175 ((random() % mudconf.payfind) == 0)) {
00176 giveto(thing, 1);
00177 notify_printf(thing, "You found a %s!", mudconf.one_coin);
00178 }
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 static void send_dropto(dbref thing, dbref player)
00192 {
00193 if(!Sticky(thing))
00194 move_via_generic(thing, Dropto(Location(thing)), player, 0);
00195 else
00196 move_via_generic(thing, HOME, player, 0);
00197 divest_object(thing);
00198
00199 }
00200
00201
00202
00203
00204
00205
00206 static void process_sticky_dropto(dbref loc, dbref player)
00207 {
00208 dbref dropto, thing, next;
00209
00210
00211
00212
00213
00214 if(!Good_obj(loc) || !Has_dropto(loc) || !Sticky(loc))
00215 return;
00216
00217
00218
00219
00220
00221 dropto = Dropto(loc);
00222 if((dropto == NOTHING) || (dropto == loc))
00223 return;
00224
00225
00226
00227
00228
00229 DOLIST(thing, Contents(loc)) {
00230 if(Dropper(thing))
00231 return;
00232 }
00233
00234
00235
00236
00237
00238 s_Contents(loc, reverse_list(Contents(loc)));
00239 SAFE_DOLIST(thing, next, Contents(loc)) {
00240 send_dropto(thing, player);
00241 }
00242 }
00243
00244
00245
00246
00247
00248 static void process_dropped_dropto(dbref thing, dbref player)
00249 {
00250 dbref loc;
00251
00252
00253
00254
00255
00256 if(Sticky(thing)) {
00257 move_via_generic(thing, HOME, player, 0);
00258 divest_object(thing);
00259 return;
00260 }
00261
00262
00263
00264
00265 loc = Location(thing);
00266 if(Has_dropto(loc) && (Dropto(loc) != NOTHING) && !Sticky(loc))
00267 send_dropto(thing, player);
00268 }
00269
00270
00271
00272
00273
00274
00275
00276 void move_via_generic(dbref thing, dbref dest, dbref cause, int hush)
00277 {
00278 dbref src;
00279 int canhear;
00280
00281 if(dest == HOME)
00282 dest = Home(thing);
00283 src = Location(thing);
00284 canhear = Hearer(thing);
00285 process_leave_loc(thing, dest, cause, canhear, hush);
00286 move_object(thing, dest);
00287 did_it(thing, thing, A_MOVE, NULL, A_OMOVE, NULL, A_AMOVE,
00288 (char **) NULL, 0);
00289 process_enter_loc(thing, src, cause, canhear, hush);
00290 }
00291
00292
00293
00294
00295
00296
00297 void move_via_exit(dbref thing, dbref dest, dbref cause, dbref exit, int hush)
00298 {
00299 dbref src;
00300 int canhear, darkwiz, quiet, pattr, oattr, aattr;
00301
00302 if(dest == HOME)
00303 dest = Home(thing);
00304 src = Location(thing);
00305 canhear = Hearer(thing);
00306
00307
00308
00309
00310
00311 darkwiz = (Wizard(thing) && Dark(thing));
00312 quiet = darkwiz || (hush & HUSH_EXIT);
00313
00314 oattr = quiet ? 0 : A_OSUCC;
00315 aattr = quiet ? 0 : A_ASUCC;
00316 pattr = (!mudconf.terse_movemsg && Terse(thing)) ? 0 : A_SUCC;
00317 did_it(thing, exit, pattr, NULL, oattr, NULL, aattr, (char **) NULL, 0);
00318 process_leave_loc(thing, dest, cause, canhear, hush);
00319 move_object(thing, dest);
00320
00321
00322
00323
00324
00325 oattr = quiet ? 0 : A_ODROP;
00326 aattr = quiet ? 0 : A_ADROP;
00327 pattr = (!mudconf.terse_movemsg && Terse(thing)) ? 0 : A_DROP;
00328 did_it(thing, exit, pattr, NULL, oattr, NULL, aattr, (char **) NULL, 0);
00329
00330 did_it(thing, thing, A_MOVE, NULL, A_OMOVE, NULL, A_AMOVE,
00331 (char **) NULL, 0);
00332 process_enter_loc(thing, src, cause, canhear, hush);
00333 process_sticky_dropto(src, thing);
00334 }
00335
00336
00337
00338
00339
00340
00341
00342 int move_via_teleport(dbref thing, dbref dest, dbref cause, int hush)
00343 {
00344 dbref src, curr;
00345 int canhear, count;
00346 char *failmsg;
00347
00348 src = Location(thing);
00349 if((dest != HOME) && Good_obj(src)) {
00350 curr = src;
00351 for(count = mudconf.ntfy_nest_lim; count > 0; count--) {
00352 if(!could_doit(thing, curr, A_LTELOUT)) {
00353 if((thing == cause) || (cause == NOTHING))
00354 failmsg = (char *)
00355 "You can't teleport out!";
00356 else {
00357 failmsg = (char *)
00358 "You can't be teleported out!";
00359 notify_quiet(cause, "You can't teleport that out!");
00360 }
00361 did_it(thing, src, A_TOFAIL, failmsg, A_OTOFAIL, NULL,
00362 A_ATOFAIL, (char **) NULL, 0);
00363 return 0;
00364 }
00365 if(isRoom(curr))
00366 break;
00367 curr = Location(curr);
00368 }
00369 }
00370 if(dest == HOME)
00371 dest = Home(thing);
00372 canhear = Hearer(thing);
00373 if(!(hush & HUSH_LEAVE))
00374 did_it(thing, thing, 0, NULL, A_OXTPORT, NULL, 0, (char **) NULL, 0);
00375 process_leave_loc(thing, dest, NOTHING, canhear, hush);
00376 move_object(thing, dest);
00377 if(!(hush & HUSH_ENTER))
00378 did_it(thing, thing, A_TPORT, NULL, A_OTPORT, NULL, A_ATPORT,
00379 (char **) NULL, 0);
00380 did_it(thing, thing, A_MOVE, NULL, A_OMOVE, NULL, A_AMOVE,
00381 (char **) NULL, 0);
00382 process_enter_loc(thing, src, NOTHING, canhear, hush);
00383 divest_object(thing);
00384 process_sticky_dropto(src, thing);
00385 return 1;
00386 }
00387
00388
00389
00390
00391
00392
00393 void move_exit(dbref player, dbref exit, int divest, const char *failmsg,
00394 int hush)
00395 {
00396 dbref loc;
00397 int oattr, aattr;
00398
00399 loc = Location(exit);
00400 if(loc == HOME)
00401 loc = Home(player);
00402 if(Good_obj(loc) && could_doit(player, exit, A_LOCK)) {
00403 switch (Typeof(loc)) {
00404 case TYPE_ROOM:
00405 move_via_exit(player, loc, NOTHING, exit, hush);
00406 if(divest)
00407 divest_object(player);
00408 break;
00409 case TYPE_PLAYER:
00410 case TYPE_THING:
00411 if(Going(loc)) {
00412 notify(player, "You can't go that way.");
00413 return;
00414 }
00415 move_via_exit(player, loc, NOTHING, exit, hush);
00416 divest_object(player);
00417 break;
00418 case TYPE_EXIT:
00419 notify(player, "You can't go that way.");
00420 return;
00421 }
00422 } else {
00423 if((Wizard(player) && Dark(player)) || (hush & HUSH_EXIT)) {
00424 oattr = 0;
00425 aattr = 0;
00426 } else {
00427 oattr = A_OFAIL;
00428 aattr = A_AFAIL;
00429 }
00430 did_it(player, exit, A_FAIL, failmsg, oattr, NULL, aattr,
00431 (char **) NULL, 0);
00432 }
00433 }
00434
00435
00436
00437
00438
00439
00440 void do_move(dbref player, dbref cause, int key, char *direction)
00441 {
00442 dbref exit, loc;
00443 int i, quiet;
00444
00445 if(!string_compare(direction, "home")) {
00446
00447
00448 if((Fixed(player) || Fixed(Owner(player))) && !(WizRoy(player))) {
00449 notify(player, mudconf.fixed_home_msg);
00450 return;
00451 }
00452
00453 if((loc = Location(player)) != NOTHING && !Dark(player) && !Dark(loc)) {
00454
00455
00456
00457
00458 char buffer[MBUF_SIZE];
00459 memset(buffer, 0, MBUF_SIZE);
00460 snprintf(buffer, MBUF_SIZE-1, "%s goes home.", Name(player));
00461 notify_except(loc, player, player, buffer);
00462 }
00463
00464
00465
00466
00467 for(i = 0; i < 3; i++)
00468 notify(player, "There's no place like home...");
00469 move_via_generic(player, HOME, NOTHING, 0);
00470 divest_object(player);
00471 process_sticky_dropto(loc, player);
00472 return;
00473 }
00474
00475
00476
00477
00478 init_match_check_keys(player, direction, TYPE_EXIT);
00479 match_exit();
00480 exit = match_result();
00481 switch (exit) {
00482 case NOTHING:
00483
00484
00485 notify(player, "You can't go that way.");
00486 break;
00487 case AMBIGUOUS:
00488 notify(player, "I don't know which way you mean!");
00489 break;
00490 default:
00491 quiet = 0;
00492 if((key & MOVE_QUIET) && Controls(player, exit))
00493 quiet = HUSH_EXIT;
00494 move_exit(player, exit, 0, "You can't go that way.", quiet);
00495 }
00496 }
00497
00498
00499
00500
00501
00502
00503 void do_get(dbref player, dbref cause, int key, char *what)
00504 {
00505 dbref thing, playerloc, thingloc;
00506 char *failmsg;
00507 int oattr, aattr, quiet;
00508
00509 playerloc = Location(player);
00510 if(!Good_obj(playerloc))
00511 return;
00512
00513
00514
00515
00516
00517 if(!isRoom(playerloc) && !Enter_ok(playerloc) &&
00518 !controls(player, playerloc)) {
00519 notify(player, "Permission denied.");
00520 return;
00521 }
00522
00523
00524
00525
00526 init_match_check_keys(player, what, TYPE_THING);
00527 match_neighbor();
00528 match_exit();
00529 if(Long_Fingers(player))
00530 match_absolute();
00531
00532
00533 thing = match_result();
00534
00535
00536
00537
00538
00539 if(!Good_obj(thing))
00540 thing =
00541 match_status(player, match_possessed(player, player, what,
00542 thing, 1));
00543 if(!Good_obj(thing))
00544 return;
00545
00546
00547
00548
00549
00550 quiet = 0;
00551 switch (Typeof(thing)) {
00552 case TYPE_PLAYER:
00553 case TYPE_THING:
00554
00555
00556
00557
00558 thingloc = Location(thing);
00559 if(thingloc == player) {
00560 notify(player, "You already have that!");
00561 break;
00562 }
00563 if((key & GET_QUIET) && Controls(player, thing))
00564 quiet = 1;
00565
00566 if(thing == player) {
00567 notify(player, "You cannot get yourself!");
00568 } else if(could_doit(player, thing, A_LOCK)) {
00569 if(thingloc != Location(player)) {
00570 notify_printf(thingloc, "%s was taken from you.",
00571 Name(thing));
00572 }
00573 move_via_generic(thing, player, player, 0);
00574 notify(thing, "Taken.");
00575 oattr = quiet ? 0 : A_OSUCC;
00576 aattr = quiet ? 0 : A_ASUCC;
00577 did_it(player, thing, A_SUCC, "Taken.", oattr, NULL, aattr,
00578 (char **) NULL, 0);
00579 } else {
00580 oattr = quiet ? 0 : A_OFAIL;
00581 aattr = quiet ? 0 : A_AFAIL;
00582 if(thingloc != Location(player))
00583 failmsg = (char *) "You can't take that from there.";
00584 else
00585 failmsg = (char *) "You can't pick that up.";
00586 did_it(player, thing, A_FAIL, failmsg, oattr, NULL, aattr,
00587 (char **) NULL, 0);
00588 }
00589 break;
00590 case TYPE_EXIT:
00591
00592
00593
00594
00595 thingloc = Exits(thing);
00596 if(thingloc == player) {
00597 notify(player, "You already have that!");
00598 break;
00599 }
00600
00601
00602
00603
00604 playerloc = Location(player);
00605 if(!Controls(player, thing) && !Controls(player, playerloc)) {
00606 notify(player, "Permission denied.");
00607 break;
00608 }
00609
00610
00611
00612
00613 s_Exits(thingloc, remove_first(Exits(thingloc), thing));
00614 s_Exits(player, insert_first(Exits(player), thing));
00615 s_Exits(thing, player);
00616 if(!Quiet(player))
00617 notify(player, "Exit taken.");
00618 break;
00619 default:
00620 notify(player, "You can't take that!");
00621 break;
00622 }
00623 }
00624
00625
00626
00627
00628
00629
00630 void do_drop(dbref player, dbref cause, int key, char *name)
00631 {
00632 dbref loc, exitloc, thing;
00633 char *buf, *bp;
00634 int quiet, oattr, aattr;
00635
00636 loc = Location(player);
00637 if(!Good_obj(loc))
00638 return;
00639
00640 init_match(player, name, TYPE_THING);
00641 match_possession();
00642 match_carried_exit();
00643
00644 switch (thing = match_result()) {
00645 case NOTHING:
00646 notify(player, "You don't have that!");
00647 return;
00648 case AMBIGUOUS:
00649 notify(player, "I don't know which you mean!");
00650 return;
00651 }
00652
00653 switch (Typeof(thing)) {
00654 case TYPE_THING:
00655 case TYPE_PLAYER:
00656
00657
00658
00659
00660
00661 if(((Location(thing) != player) && !Wizard(player)) ||
00662 (!could_doit(player, thing, A_LDROP))) {
00663 did_it(player, thing, A_DFAIL, "You can't drop that.",
00664 A_ODFAIL, NULL, A_ADFAIL, (char **) NULL, 0);
00665 return;
00666 }
00667
00668
00669
00670
00671 move_via_generic(thing, Location(player), player, 0);
00672 notify(thing, "Dropped.");
00673 quiet = 0;
00674 if((key & DROP_QUIET) && Controls(player, thing))
00675 quiet = 1;
00676 bp = buf = alloc_lbuf("do_drop.did_it");
00677 safe_tprintf_str(buf, &bp, "dropped %s.", Name(thing));
00678 oattr = quiet ? 0 : A_ODROP;
00679 aattr = quiet ? 0 : A_ADROP;
00680 did_it(player, thing, A_DROP, "Dropped.", oattr, buf, aattr,
00681 (char **) NULL, 0);
00682 free_lbuf(buf);
00683
00684
00685
00686
00687
00688 process_dropped_dropto(thing, player);
00689
00690 break;
00691 case TYPE_EXIT:
00692
00693
00694
00695
00696
00697 if((Exits(thing) != player) && !Wizard(player)) {
00698 notify(player, "You can't drop that.");
00699 return;
00700 }
00701 if(!Controls(player, loc)) {
00702 notify(player, "Permission denied.");
00703 return;
00704 }
00705
00706
00707
00708
00709 exitloc = Exits(thing);
00710 s_Exits(exitloc, remove_first(Exits(exitloc), thing));
00711 s_Exits(loc, insert_first(Exits(loc), thing));
00712 s_Exits(thing, loc);
00713
00714 if(!Quiet(player))
00715 notify(player, "Exit dropped.");
00716 break;
00717 default:
00718 notify(player, "You can't drop that.");
00719 }
00720
00721 }
00722
00723
00724
00725
00726
00727
00728 void do_enter_internal(dbref player, dbref thing, int quiet)
00729 {
00730 dbref loc = Location(player);
00731 int oattr, aattr;
00732
00733 if(!Enter_ok(thing) && !controls(player, thing)) {
00734 oattr = quiet ? 0 : A_OEFAIL;
00735 aattr = quiet ? 0 : A_AEFAIL;
00736 did_it(player, thing, A_EFAIL, "Permission denied.", oattr, NULL,
00737 aattr, (char **) NULL, 0);
00738 } else if(player == thing) {
00739 notify(player, "You can't enter yourself!");
00740 #ifdef ENTER_REQUIRES_LEAVESUCC
00741 } else if(could_doit(player, thing, A_LENTER) &&
00742 could_doit(player, loc, A_LLEAVE))
00743 #else
00744 } else if(could_doit(player, thing, A_LENTER))
00745 #endif
00746 {
00747 oattr = quiet ? HUSH_ENTER : 0;
00748 move_via_generic(player, thing, NOTHING, oattr);
00749 divest_object(player);
00750 process_sticky_dropto(loc, player);
00751 } else {
00752 oattr = quiet ? 0 : A_OEFAIL;
00753 aattr = quiet ? 0 : A_AEFAIL;
00754 did_it(player, thing, A_EFAIL, "You can't enter that.", oattr,
00755 NULL, aattr, (char **) NULL, 0);
00756 }
00757 }
00758
00759 void do_enter(dbref player, dbref cause, int key, char *what)
00760 {
00761 dbref thing;
00762 int quiet;
00763
00764 init_match(player, what, TYPE_THING);
00765 match_neighbor();
00766 if(Long_Fingers(player))
00767 match_absolute();
00768
00769
00770
00771 if((thing = noisy_match_result()) == NOTHING)
00772 return;
00773
00774 switch (Typeof(thing)) {
00775 case TYPE_PLAYER:
00776 case TYPE_THING:
00777 quiet = 0;
00778 if((key & MOVE_QUIET) && Controls(player, thing))
00779 quiet = 1;
00780 do_enter_internal(player, thing, quiet);
00781 break;
00782 default:
00783 notify(player, "Permission denied.");
00784 }
00785 return;
00786 }
00787
00788 void do_leave(dbref player, dbref cause, int key)
00789 {
00790 dbref loc;
00791 int quiet, oattr, aattr;
00792
00793 loc = Location(player);
00794
00795 if(!Good_obj(loc) || isRoom(loc) || Going(loc)) {
00796 notify(player, "You can't leave.");
00797 return;
00798 }
00799 quiet = 0;
00800 if((key & MOVE_QUIET) && Controls(player, loc))
00801 quiet = HUSH_LEAVE;
00802 #ifdef LEAVE_REQUIRES_ENTERSUCC
00803 if(could_doit(player, loc, A_LLEAVE) &&
00804 could_doit(player, Location(loc), A_LENTER)) {
00805 #else
00806 if(could_doit(player, loc, A_LLEAVE)) {
00807 #endif
00808 move_via_generic(player, Location(loc), NOTHING, quiet);
00809 } else {
00810 oattr = quiet ? 0 : A_OLFAIL;
00811 aattr = quiet ? 0 : A_ALFAIL;
00812 did_it(player, loc, A_LFAIL, "You can't leave.", oattr, NULL,
00813 aattr, (char **) NULL, 0);
00814 }
00815 }