00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00040 #include <global.h>
00041 #include <object.h>
00042 #include <newclient.h>
00043 #include <newserver.h>
00044 #include <sproto.h>
00045
00047 #define MAXITEMLEN 300
00048
00049
00050
00051
00052
00053
00054
00055
00060 static unsigned int query_flags(const object *op) {
00061 unsigned int flags = 0;
00062
00063 if (QUERY_FLAG(op, FLAG_APPLIED)) {
00064 switch (op->type) {
00065 case BOW:
00066 case WAND:
00067 case ROD:
00068 case HORN:
00069 flags = a_readied;
00070 break;
00071
00072 case WEAPON:
00073 flags = a_wielded;
00074 break;
00075
00076 case SKILL:
00077 case ARMOUR:
00078 case HELMET:
00079 case SHIELD:
00080 case RING:
00081 case BOOTS:
00082 case GLOVES:
00083 case AMULET:
00084 case GIRDLE:
00085 case BRACERS:
00086 case CLOAK:
00087 flags = a_worn;
00088 break;
00089
00090 case CONTAINER:
00091 flags = a_active;
00092 break;
00093
00094 default:
00095 flags = a_applied;
00096 break;
00097 }
00098 }
00099 if (op->type == CONTAINER
00100 && ((op->env && op->env->container == op) || (!op->env && QUERY_FLAG(op, FLAG_APPLIED))))
00101 flags |= F_OPEN;
00102
00103 if (QUERY_FLAG(op, FLAG_KNOWN_CURSED)) {
00104 if (QUERY_FLAG(op, FLAG_DAMNED))
00105 flags |= F_DAMNED;
00106 else if (QUERY_FLAG(op, FLAG_CURSED))
00107 flags |= F_CURSED;
00108 }
00109 if (QUERY_FLAG(op, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG(op, FLAG_IDENTIFIED))
00110 flags |= F_MAGIC;
00111 if (QUERY_FLAG(op, FLAG_UNPAID))
00112 flags |= F_UNPAID;
00113 if (QUERY_FLAG(op, FLAG_INV_LOCKED))
00114 flags |= F_LOCKED;
00115 if (QUERY_FLAG(op, FLAG_KNOWN_BLESSED) && QUERY_FLAG(op, FLAG_BLESSED))
00116 flags |= F_BLESSED;
00117
00118 return flags;
00119 }
00120
00126 static void add_object_to_socklist(socket_struct *ns, SockList *sl, object *head) {
00127 int flags, len, anim_speed;
00128 char item_n[MAX_BUF], item_p[MAX_BUF];
00129
00130 flags = query_flags(head);
00131 if (QUERY_FLAG(head, FLAG_NO_PICK))
00132 flags |= F_NOPICK;
00133
00134 if (!(ns->faces_sent[head->face->number]&NS_FACESENT_FACE))
00135 esrv_send_face(ns, head->face->number, 0);
00136
00137 if (QUERY_FLAG(head, FLAG_ANIMATE) && !ns->anims_sent[head->animation_id])
00138 esrv_send_animation(ns, head->animation_id);
00139
00140 SockList_AddInt(sl, head->count);
00141 SockList_AddInt(sl, flags);
00142 SockList_AddInt(sl, QUERY_FLAG(head, FLAG_NO_PICK) ? -1 : WEIGHT(head));
00143 SockList_AddInt(sl, head->face->number);
00144
00145 if (!head->custom_name) {
00146 query_base_name(head, 0, item_n, 126);
00147 item_n[127] = 0;
00148 len = strlen(item_n);
00149 query_base_name(head, 1, item_p, MAX_BUF);
00150 } else {
00151 strncpy(item_n, head->custom_name, 127);
00152 item_n[127] = 0;
00153 len = strlen(item_n);
00154 strncpy(item_p, head->custom_name, MAX_BUF);
00155 }
00156 strncpy(item_n+len+1, item_p, 127);
00157
00158 item_n[len+1+127] = 0;
00159 len += strlen(item_n+1+len)+1;
00160 SockList_AddLen8Data(sl, item_n, len);
00161
00162 SockList_AddShort(sl, head->animation_id);
00163 anim_speed = 0;
00164 if (QUERY_FLAG(head, FLAG_ANIMATE)) {
00165 if (head->anim_speed)
00166 anim_speed = head->anim_speed;
00167 else {
00168 if (FABS(head->speed) < 0.001)
00169 anim_speed = 255;
00170 else if (FABS(head->speed) >= 1.0)
00171 anim_speed = 1;
00172 else
00173 anim_speed = (int)(1.0/FABS(head->speed));
00174 }
00175 if (anim_speed > 255)
00176 anim_speed = 255;
00177 }
00178 SockList_AddChar(sl, (char)anim_speed);
00179 SockList_AddInt(sl, head->nrof);
00180
00181 SockList_AddShort(sl, head->client_type);
00182
00183 SET_FLAG(head, FLAG_CLIENT_SENT);
00184 }
00185
00191 void esrv_draw_look(object *pl) {
00192 object *tmp, *last;
00193 int got_one = 0, start_look = 0, end_look = 0, objects_sent = 0;
00194 SockList sl;
00195 char buf[MAX_BUF];
00196
00197 if (!pl->contr->socket.update_look) {
00198 LOG(llevDebug, "esrv_draw_look called when update_look was not set\n");
00199 return;
00200 } else {
00201 pl->contr->socket.update_look = 0;
00202 }
00203
00204 if (QUERY_FLAG(pl, FLAG_REMOVED)
00205 || pl->map == NULL
00206 || pl->map->in_memory != MAP_IN_MEMORY
00207 || out_of_map(pl->map, pl->x, pl->y))
00208 return;
00209
00210 if (pl->contr->transport)
00211 for (tmp = pl->contr->transport->inv; tmp && tmp->above; tmp = tmp->above)
00212 ;
00213 else
00214 for (tmp = GET_MAP_OB(pl->map, pl->x, pl->y); tmp && tmp->above; tmp = tmp->above)
00215 ;
00216
00217 SockList_Init(&sl);
00218 SockList_AddString(&sl, "delinv 0");
00219 Send_With_Handling(&pl->contr->socket, &sl);
00220
00221 SockList_Reset(&sl);
00222 SockList_AddPrintf(&sl, "item2 ");
00223 SockList_AddInt(&sl, 0);
00224
00225 if (!(pl->contr->socket.faces_sent[empty_face->number]&NS_FACESENT_FACE))
00226 esrv_send_face(&pl->contr->socket, empty_face->number, 0);
00227
00228 if (pl->contr->socket.look_position) {
00229 int overhead = 1+(pl->contr->transport != NULL);
00230 int prev_len = pl->contr->socket.num_look_objects-overhead-(pl->contr->socket.look_position > pl->contr->socket.num_look_objects-overhead);
00231 SockList_AddInt(&sl, 0x80000000|MAX(0, pl->contr->socket.look_position-prev_len));
00232 SockList_AddInt(&sl, 0);
00233 SockList_AddInt(&sl, -1);
00234 SockList_AddInt(&sl, empty_face->number);
00235 snprintf(buf, sizeof(buf), "Click here to see previous group of items");
00236 SockList_AddLen8Data(&sl, buf, MIN(strlen(buf), 255));
00237 SockList_AddShort(&sl, 0);
00238 SockList_AddChar(&sl, 0);
00239 SockList_AddInt(&sl, 0);
00240 SockList_AddShort(&sl, 0);
00241 objects_sent++;
00242 got_one++;
00243 }
00244
00245 if (pl->contr->transport) {
00246 add_object_to_socklist(&pl->contr->socket, &sl, pl->contr->transport);
00247 objects_sent++;
00248 got_one++;
00249 }
00250
00251 for (last = NULL; tmp != last; tmp = tmp->below) {
00252 object *head;
00253
00254 if (QUERY_FLAG(tmp, FLAG_IS_FLOOR) && !last) {
00255 last = tmp->below;
00256 if (last && QUERY_FLAG(last, FLAG_IS_FLOOR))
00257 last = last->below;
00258 }
00259 if (LOOK_OBJ(tmp)) {
00260 if (start_look++ < pl->contr->socket.look_position)
00261 continue;
00262 end_look++;
00263 objects_sent++;
00264 if (objects_sent >= pl->contr->socket.num_look_objects) {
00265
00266
00267
00268
00269 SockList_AddInt(&sl, 0x80000000|(pl->contr->socket.look_position+end_look-1));
00270 SockList_AddInt(&sl, 0);
00271 SockList_AddInt(&sl, -1);
00272 SockList_AddInt(&sl, empty_face->number);
00273 snprintf(buf, sizeof(buf), "Click here to see next group of items");
00274 SockList_AddLen8Data(&sl, buf, MIN(strlen(buf), 255));
00275 SockList_AddShort(&sl, 0);
00276 SockList_AddChar(&sl, 0);
00277 SockList_AddInt(&sl, 0);
00278 SockList_AddShort(&sl, 0);
00279 break;
00280 }
00281 if (tmp->head)
00282 head = tmp->head;
00283 else
00284 head = tmp;
00285
00286 add_object_to_socklist(&pl->contr->socket, &sl, head);
00287 got_one++;
00288
00289 if (SockList_Avail(&sl) < MAXITEMLEN) {
00290 Send_With_Handling(&pl->contr->socket, &sl);
00291 SockList_Reset(&sl);
00292 SockList_AddPrintf(&sl, "item2 ");
00293 SockList_AddInt(&sl, 0);
00294 got_one = 0;
00295 }
00296 }
00297 }
00298 if (got_one)
00299 Send_With_Handling(&pl->contr->socket, &sl);
00300
00301 SockList_Term(&sl);
00302 }
00303
00307 void esrv_send_inventory(object *pl, object *op) {
00308 object *tmp;
00309 int got_one = 0;
00310 SockList sl;
00311
00312 SockList_Init(&sl);
00313 SockList_AddPrintf(&sl, "delinv %u", op->count);
00314 Send_With_Handling(&pl->contr->socket, &sl);
00315
00316 SockList_Reset(&sl);
00317 SockList_AddString(&sl, "item2 ");
00318 SockList_AddInt(&sl, op->count);
00319
00320 for (tmp = op->inv; tmp; tmp = tmp->below) {
00321 object *head;
00322
00323 if (tmp->head)
00324 head = tmp->head;
00325 else
00326 head = tmp;
00327
00328 if (LOOK_OBJ(head)) {
00329 add_object_to_socklist(&pl->contr->socket, &sl, head);
00330
00331 got_one++;
00332
00333
00334
00335
00336
00337 if (SockList_Avail(&sl) < MAXITEMLEN) {
00338 Send_With_Handling(&pl->contr->socket, &sl);
00339 SockList_Reset(&sl);
00340 SockList_AddString(&sl, "item2 ");
00341 SockList_AddInt(&sl, op->count);
00342 got_one = 0;
00343 }
00344 }
00345 }
00346 if (got_one)
00347 Send_With_Handling(&pl->contr->socket, &sl);
00348 SockList_Term(&sl);
00349 }
00350
00359 void esrv_update_item(int flags, object *pl, object *op) {
00360 SockList sl;
00361
00362 if (!pl->contr)
00363 return;
00364
00365
00366 if (op != pl) {
00367 if (!LOOK_OBJ(op))
00368 return;
00369
00370
00371
00372
00373 }
00374 if (!QUERY_FLAG(op, FLAG_CLIENT_SENT)) {
00375
00376
00377
00378
00379 LOG(llevDebug, "We have not sent item %s (%d)\n", op->name, op->count);
00380 }
00381
00382 SockList_Init(&sl);
00383 SockList_AddString(&sl, "upditem ");
00384 SockList_AddChar(&sl, (char)flags);
00385
00386 if (op->head)
00387 op = op->head;
00388
00389 SockList_AddInt(&sl, op->count);
00390
00391 if (flags&UPD_LOCATION)
00392 SockList_AddInt(&sl, op->env ? op->env->count : 0);
00393
00394 if (flags&UPD_FLAGS)
00395 SockList_AddInt(&sl, query_flags(op));
00396
00397 if (flags&UPD_WEIGHT) {
00398 sint32 weight = WEIGHT(op);
00399
00400
00401
00402
00403
00404
00405 SockList_AddInt(&sl, QUERY_FLAG(op, FLAG_NO_PICK) ? -1 : weight);
00406 if (pl == op) {
00407 op->contr->last_weight = weight;
00408 }
00409 }
00410
00411 if (flags&UPD_FACE) {
00412 if (!(pl->contr->socket.faces_sent[op->face->number]&NS_FACESENT_FACE))
00413 esrv_send_face(&pl->contr->socket, op->face->number, 0);
00414 SockList_AddInt(&sl, op->face->number);
00415 }
00416 if (flags&UPD_NAME) {
00417 int len;
00418 char item_p[MAX_BUF];
00419 char item_n[MAX_BUF];
00420
00421 if (!op->custom_name) {
00422 query_base_name(op, 0, item_n, MAX_BUF);
00423 len = strlen(item_n);
00424 query_base_name(op, 1, item_p, MAX_BUF);
00425 } else {
00426 strncpy(item_n, op->custom_name, MAX_BUF-1);
00427 item_n[MAX_BUF-1] = 0;
00428 len = strlen(item_n);
00429 strncpy(item_p, op->custom_name, MAX_BUF-1);
00430 item_p[MAX_BUF-1] = 0;
00431 }
00432
00433 strncpy(item_n+len+1, item_p, 127);
00434 item_n[254] = 0;
00435 len += strlen(item_n+1+len)+1;
00436 SockList_AddLen8Data(&sl, item_n, len);
00437 }
00438 if (flags&UPD_ANIM)
00439 SockList_AddShort(&sl, op->animation_id);
00440
00441 if (flags&UPD_ANIMSPEED) {
00442 int anim_speed = 0;
00443
00444 if (QUERY_FLAG(op, FLAG_ANIMATE)) {
00445 if (op->anim_speed)
00446 anim_speed = op->anim_speed;
00447 else {
00448 if (FABS(op->speed) < 0.001)
00449 anim_speed = 255;
00450 else if (FABS(op->speed) >= 1.0)
00451 anim_speed = 1;
00452 else
00453 anim_speed = (int)(1.0/FABS(op->speed));
00454 }
00455 if (anim_speed > 255)
00456 anim_speed = 255;
00457 }
00458 SockList_AddChar(&sl, (char)anim_speed);
00459 }
00460 if (flags&UPD_NROF)
00461 SockList_AddInt(&sl, op->nrof);
00462
00463 Send_With_Handling(&pl->contr->socket, &sl);
00464 SockList_Term(&sl);
00465 }
00466
00470 void esrv_send_item(object *pl, object*op) {
00471 SockList sl;
00472
00473
00474 if (op != pl) {
00475
00476 if (!LOOK_OBJ(op))
00477 return;
00478
00479
00480
00481 if (!op->env) {
00482 pl->contr->socket.update_look = 1;
00483 return;
00484 }
00485 }
00486
00487 SockList_Init(&sl);
00488 SockList_AddString(&sl, "item2 ");
00489
00490 if (op->head)
00491 op = op->head;
00492
00493 SockList_AddInt(&sl, op->env ? op->env->count : 0);
00494
00495 add_object_to_socklist(&pl->contr->socket, &sl, op);
00496
00497 Send_With_Handling(&pl->contr->socket, &sl);
00498 SET_FLAG(op, FLAG_CLIENT_SENT);
00499 SockList_Term(&sl);
00500 }
00501
00507 void esrv_del_item(player *pl, int tag) {
00508 SockList sl;
00509
00510 SockList_Init(&sl);
00511 SockList_AddString(&sl, "delitem ");
00512 SockList_AddInt(&sl, tag);
00513 Send_With_Handling(&pl->socket, &sl);
00514 SockList_Term(&sl);
00515 }
00516
00517
00518
00519
00520
00521
00522
00523
00529 static object *esrv_get_ob_from_count(object *pl, tag_t count) {
00530 object *op, *tmp;
00531
00532 if (pl->count == count)
00533 return pl;
00534
00535 for (op = pl->inv; op; op = op->below)
00536 if (op->count == count)
00537 return op;
00538 else if (op->type == CONTAINER && pl->container == op)
00539 for (tmp = op->inv; tmp; tmp = tmp->below)
00540 if (tmp->count == count)
00541 return tmp;
00542
00543 for (op = GET_MAP_OB(pl->map, pl->x, pl->y); op; op = op->above)
00544 if (op->head != NULL && op->head->count == count)
00545 return op;
00546 else if (op->count == count)
00547 return op;
00548 else if (op->type == CONTAINER && pl->container == op)
00549 for (tmp = op->inv; tmp; tmp = tmp->below)
00550 if (tmp->count == count)
00551 return tmp;
00552
00553 if (pl->contr->transport) {
00554 for (tmp = pl->contr->transport->inv; tmp; tmp = tmp->below)
00555 if (tmp->count == count)
00556 return tmp;
00557 }
00558 return NULL;
00559 }
00560
00562 void examine_cmd(char *buf, int len, player *pl) {
00563 long tag;
00564 object *op;
00565
00566 if (len <= 0 || !buf) {
00567 LOG(llevDebug, "Player '%s' sent bogus examine_cmd information\n", pl->ob->name);
00568 return;
00569 }
00570
00571 tag = atoi(buf);
00572 op = esrv_get_ob_from_count(pl->ob, tag);
00573 if (!op) {
00574 LOG(llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", pl->ob->name, tag);
00575 return;
00576 }
00577 examine(pl->ob, op);
00578 }
00579
00581 void apply_cmd(char *buf, int len, player *pl) {
00582 uint32 tag;
00583 object *op;
00584
00585 if (!buf || len <= 0) {
00586 LOG(llevDebug, "Player '%s' sent bogus apply_cmd information\n", pl->ob->name);
00587 return;
00588 }
00589
00590 tag = atoi(buf);
00591 op = esrv_get_ob_from_count(pl->ob, tag);
00592
00593
00594
00595
00596
00597 if (QUERY_FLAG(pl->ob, FLAG_REMOVED))
00598 return;
00599
00600
00601 if (tag&0x80000000) {
00602 pl->socket.look_position = tag&0x7fffffff;
00603 pl->socket.update_look = 1;
00604 return;
00605 }
00606
00607 if (!op) {
00608 LOG(llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", pl->ob->name, tag);
00609 return;
00610 }
00611 player_apply(pl->ob, op, 0, 0);
00612 }
00613
00615 void lock_item_cmd(uint8 *data, int len, player *pl) {
00616 int flag, tag;
00617 object *op;
00618 object *tmp;
00619
00620 if (len != 5) {
00621 LOG(llevDebug, "Player '%s' sent bogus lock_item_cmd information\n", pl->ob->name);
00622 return;
00623 }
00624 flag = data[0];
00625 tag = GetInt_String(data+1);
00626 op = esrv_get_ob_from_count(pl->ob, tag);
00627
00628 if (!op) {
00629 draw_ext_info(NDI_UNIQUE, 0, pl->ob, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00630 "Could not find object to lock/unlock", NULL);
00631 return;
00632 }
00633 if (!flag)
00634 CLEAR_FLAG(op, FLAG_INV_LOCKED);
00635 else
00636 SET_FLAG(op, FLAG_INV_LOCKED);
00637
00638 tmp = merge_ob(op, NULL);
00639 if (tmp == NULL) {
00640
00641 esrv_update_item(UPD_FLAGS, pl->ob, op);
00642 }
00643 }
00644
00655 void mark_item_cmd(uint8 *data, int len, player *pl) {
00656 int tag;
00657 object *op;
00658 char name[MAX_BUF];
00659
00660 if (len != 4) {
00661 LOG(llevDebug, "Player '%s' sent bogus mark_item_cmd information\n", pl->ob->name);
00662 return;
00663 }
00664
00665 tag = GetInt_String(data);
00666 op = esrv_get_ob_from_count(pl->ob, tag);
00667 if (!op) {
00668 draw_ext_info(NDI_UNIQUE, 0, pl->ob, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00669 "Could not find object to mark", NULL);
00670 return;
00671 }
00672 pl->mark = op;
00673 pl->mark_count = op->count;
00674 query_name(op, name, MAX_BUF);
00675 draw_ext_info_format(NDI_UNIQUE, 0, pl->ob, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00676 "Marked item %s",
00677 "Marked item %s",
00678 name);
00679 }
00680
00687 void look_at(object *op, int dx, int dy) {
00688 object *tmp;
00689 int flag = 0;
00690 sint16 x, y;
00691 mapstruct *m;
00692 char name[MAX_BUF];
00693
00694 if (out_of_map(op->map, op->x+dx, op->y+dy))
00695 return;
00696
00697 x = op->x+dx;
00698 y = op->y+dy;
00699
00700 m = get_map_from_coord(op->map, &x, &y);
00701 if (!m)
00702 return;
00703
00704 for (tmp = GET_MAP_OB(m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above)
00705 ;
00706
00707 for (; tmp != NULL; tmp = tmp->below) {
00708 if (tmp->invisible && !QUERY_FLAG(op, FLAG_WIZ))
00709 continue;
00710
00711 if (!flag) {
00712 if (dx || dy)
00713 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00714 "There you see:", NULL);
00715 else {
00716 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00717 "You see:", NULL);
00718 }
00719 flag = 1;
00720 }
00721
00722 query_name(tmp, name, MAX_BUF);
00723 if (QUERY_FLAG(op, FLAG_WIZ))
00724 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
00725 "- %s (%d).",
00726 "- %s (%d).",
00727 name, tmp->count);
00728 else
00729 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
00730 "- %s.",
00731 "- %s.",
00732 name);
00733
00734 if (((tmp->inv != NULL || (tmp->head && tmp->head->inv)) && (tmp->type != CONTAINER && tmp->type != FLESH))
00735 || QUERY_FLAG(op, FLAG_WIZ))
00736 inventory(op, tmp->head == NULL ? tmp : tmp->head);
00737
00738
00739 if (QUERY_FLAG(tmp, FLAG_IS_FLOOR) && !QUERY_FLAG(op, FLAG_WIZ))
00740 break;
00741 }
00742
00743 if (!flag) {
00744 if (dx || dy)
00745 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00746 "You see nothing there.", NULL);
00747 else
00748 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00749 "You see nothing.", NULL);
00750 }
00751 }
00752
00754 void look_at_cmd(char *buf, int len, player *pl) {
00755 int dx, dy;
00756 char *cp;
00757
00758 dx = atoi(buf);
00759 if (!(cp = strchr(buf, ' '))) {
00760 return;
00761 }
00762 dy = atoi(cp);
00763
00764 if (FABS(dx) > MAP_CLIENT_X/2 || FABS(dy) > MAP_CLIENT_Y/2)
00765 return;
00766
00767 if (pl->blocked_los[dx+(pl->socket.mapx/2)][dy+(pl->socket.mapy/2)])
00768 return;
00769 look_at(pl->ob, dx, dy);
00770 }
00771
00773 void esrv_move_object(object *pl, tag_t to, tag_t tag, long nrof) {
00774 object *op, *env;
00775
00776 op = esrv_get_ob_from_count(pl, tag);
00777 if (!op) {
00778 LOG(llevDebug, "Player '%s' tried to move an unknown object (%lu)\n", pl->name, (unsigned long)tag);
00779 return;
00780 }
00781
00782
00783
00784
00785 if (!to && !pl->contr->transport) {
00786
00787
00788 if (op->map && !op->env) {
00789
00790 return;
00791 }
00792
00793
00794
00795 if (op->inv && QUERY_FLAG(op, FLAG_APPLIED)) {
00796 object *current, *next;
00797
00798 for (current = op->inv; current != NULL; current = next) {
00799 next = current->below;
00800 drop_object(pl, current, 0);
00801 }
00802 esrv_update_item(UPD_WEIGHT, pl, op);
00803 } else {
00804 drop_object(pl, op, nrof);
00805 }
00806 return;
00807 } else if (to == pl->count) {
00808
00809 if (op->env == pl)
00810 return;
00811
00812 pl->contr->count = nrof;
00813 pick_up(pl, op);
00814 return;
00815 }
00816
00817 if (pl->contr->transport) {
00818 if (can_pick(pl, op)
00819 && transport_can_hold(pl->contr->transport, op, nrof)) {
00820 put_object_in_sack(pl, pl->contr->transport, op, nrof);
00821 }
00822 } else {
00823 env = esrv_get_ob_from_count(pl, to);
00824 if (!env) {
00825 LOG(llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", pl->name, to);
00826 return;
00827 }
00828
00829
00830
00831
00832
00833 if (env->type == CONTAINER
00834 && can_pick(pl, op)
00835 && sack_can_hold(pl, env, op, nrof)) {
00836 put_object_in_sack(pl, env, op, nrof);
00837 }
00838 }
00839 }
00840
00841 void inscribe_scroll_cmd(char *buf, int len, player *pl) {
00842 object *scroll, *spell, *marked, *inscription, *currentspell;
00843 tag_t tscroll, tspell, tmarked;
00844 char type;
00845
00846 if (len < 1) {
00847 LOG(llevDebug, "Player %s sent an invalid inscribe command.\n", pl->ob->name);
00848 return;
00849 }
00850
00851 type = buf[0];
00852
00853 inscription = find_skill_by_name(pl->ob, "inscription");
00854 if (!inscription) {
00855 draw_ext_info(NDI_UNIQUE, 0, pl->ob, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You don't know how to write!", NULL);
00856 return;
00857 }
00858
00859 if (type == 0) {
00860 if (len != 9) {
00861 LOG(llevDebug, "Player %s sent an invalid inscribe command.\n", pl->ob->name);
00862 return;
00863 }
00864 tscroll = GetInt_String((uint8 *)buf+1);
00865 tspell = GetInt_String((uint8 *)buf+5);
00866
00867 scroll = esrv_get_ob_from_count(pl->ob, tscroll);
00868 if (!scroll) {
00869 LOG(llevDebug, "Player %s sent an invalid scroll for inscribe command.\n", pl->ob->name);
00870 return;
00871 }
00872
00873 spell = esrv_get_ob_from_count(pl->ob, tspell);
00874 if (!spell) {
00875 LOG(llevDebug, "Player %s sent an invalid spell for inscribe command.\n", pl->ob->name);
00876 return;
00877 }
00878
00879 tmarked = pl->mark_count;
00880 marked = pl->mark;
00881 currentspell = pl->ranges[range_magic];
00882
00883 pl->mark_count = tscroll;
00884 pl->mark = scroll;
00885 pl->ranges[range_magic] = spell;
00886
00887 write_on_item(pl->ob, "", inscription);
00888
00889 pl->mark_count = tmarked;
00890 pl->mark = marked;
00891 pl->ranges[range_magic] = currentspell;
00892 } else {
00893 }
00894 }