ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/item.C
(Generate patch)

Comparing deliantra/server/socket/item.C (file contents):
Revision 1.5 by root, Sun Sep 10 13:43:33 2006 UTC vs.
Revision 1.16 by root, Thu Dec 14 01:21:58 2006 UTC

1
2/*
3 * static char *rcsid_item_c =
4 * "$Id: item.C,v 1.5 2006/09/10 13:43:33 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The author can be reached via e-mail to crossfire-devel@real-time.com 21 The author can be reached via e-mail to <crossfire@schmorp.de>
28*/ 22*/
29 23
30/** 24/**
31 * \file 25 * \file
32 * Client/server logic. 26 * Client/server logic.
51/******************************************************************************* 45/*******************************************************************************
52 * 46 *
53 * Functions related to sending object data to the client. 47 * Functions related to sending object data to the client.
54 * 48 *
55 ******************************************************************************/ 49 ******************************************************************************/
56
57/**
58 * Adds string to socklist.
59 *
60 * This is a simple function that we use a lot here. It basically
61 * adds the specified buffer into the socklist, but prepends a
62 * single byte in length. If the data is longer than that byte, it is
63 * truncated approprately.
64 */
65inline void
66add_stringlen_to_sockbuf (const char *buf, SockList * sl)
67{
68 int len;
69
70 len = strlen (buf);
71 if (len > 255)
72 len = 255;
73 SockList_AddChar (sl, (char) len);
74 strncpy ((char *) sl->buf + sl->len, buf, len);
75 sl->len += len;
76}
77 50
78/** 51/**
79 * This is a similar to query_name, but returns flags 52 * This is a similar to query_name, but returns flags
80 * to be sended to client. 53 * to be sended to client.
81 */ 54 */
136 flags |= F_LOCKED; 109 flags |= F_LOCKED;
137 110
138 return flags; 111 return flags;
139} 112}
140 113
141/* Used in the send_look to put object head into SockList 114/* Used in the send_look to put object head into packet
142 * sl for socket ns. Need socket to know if we need to send 115 * sl for socket ns. Need socket to know if we need to send
143 * animation of face to the client. 116 * animation of face to the client.
144 */ 117 */
145static void 118static void
146add_object_to_socklist (NewSocket * ns, SockList * sl, object *head) 119add_object_to_socklist (NewSocket &ns, packet &sl, object *head)
147{ 120{
148 int flags, len, anim_speed; 121 int flags, len, anim_speed;
149 char item_n[MAX_BUF]; 122 char item_n[MAX_BUF];
150 const char *item_p; 123 const char *item_p;
151 124
152 flags = query_flags (head); 125 flags = query_flags (head);
153 if (QUERY_FLAG (head, FLAG_NO_PICK)) 126 if (QUERY_FLAG (head, FLAG_NO_PICK))
154 flags |= F_NOPICK; 127 flags |= F_NOPICK;
155 128
156 if (!(ns->faces_sent[head->face->number] & NS_FACESENT_FACE)) 129 if (!(ns.faces_sent[head->face->number] & NS_FACESENT_FACE))
157 esrv_send_face (ns, head->face->number, 0); 130 esrv_send_face (&ns, head->face->number, 0);
158 131
159 if (QUERY_FLAG (head, FLAG_ANIMATE) && !ns->anims_sent[head->animation_id]) 132 if (QUERY_FLAG (head, FLAG_ANIMATE) && !ns.anims_sent[head->animation_id])
160 esrv_send_animation (ns, head->animation_id); 133 esrv_send_animation (&ns, head->animation_id);
161 134
162 SockList_AddInt (sl, head->count); 135 sl << uint32 (head->count)
163 SockList_AddInt (sl, flags); 136 << uint32 (flags)
164 SockList_AddInt (sl, QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : WEIGHT (head)); 137 << uint32 (QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : WEIGHT (head))
165 SockList_AddInt (sl, head->face->number); 138 << uint32 (head->face->number);
166 139
167 if (!head->custom_name) 140 if (!head->custom_name)
168 { 141 {
169 strncpy (item_n, query_base_name (head, 0), 127); 142 strncpy (item_n, query_base_name (head, 0), 127);
170 item_n[127] = 0; 143 item_n[127] = 0;
176 strncpy (item_n, head->custom_name, 127); 149 strncpy (item_n, head->custom_name, 127);
177 item_n[127] = 0; 150 item_n[127] = 0;
178 len = strlen (item_n); 151 len = strlen (item_n);
179 item_p = head->custom_name; 152 item_p = head->custom_name;
180 } 153 }
154
181 strncpy (item_n + len + 1, item_p, 127); 155 strncpy (item_n + len + 1, item_p, 127);
182 item_n[254] = 0; 156 item_n[254] = 0;
183 len += strlen (item_n + 1 + len) + 1; 157 len += strlen (item_n + 1 + len) + 1;
184 SockList_AddChar (sl, (char) len);
185 memcpy (sl->buf + sl->len, item_n, len);
186 sl->len += len;
187 158
188 SockList_AddShort (sl, head->animation_id); 159 sl << data8 (item_n, len)
160 << uint16 (head->animation_id);
161
189 anim_speed = 0; 162 anim_speed = 0;
190 if (QUERY_FLAG (head, FLAG_ANIMATE)) 163 if (QUERY_FLAG (head, FLAG_ANIMATE))
191 { 164 {
192 if (head->anim_speed) 165 if (head->anim_speed)
193 anim_speed = head->anim_speed; 166 anim_speed = head->anim_speed;
198 else if (FABS (head->speed) >= 1.0) 171 else if (FABS (head->speed) >= 1.0)
199 anim_speed = 1; 172 anim_speed = 1;
200 else 173 else
201 anim_speed = (int) (1.0 / FABS (head->speed)); 174 anim_speed = (int) (1.0 / FABS (head->speed));
202 } 175 }
176
203 if (anim_speed > 255) 177 if (anim_speed > 255)
204 anim_speed = 255; 178 anim_speed = 255;
205 } 179 }
206 SockList_AddChar (sl, (char) anim_speed);
207 SockList_AddInt (sl, head->nrof);
208 180
181 sl << uint8 (anim_speed)
182 << uint32 (head->nrof);
183
209 if (ns->itemcmd == 2) 184 if (ns.itemcmd == 2)
210 SockList_AddShort (sl, head->client_type); 185 sl << uint16 (head->client_type);
211 186
212 SET_FLAG (head, FLAG_CLIENT_SENT); 187 SET_FLAG (head, FLAG_CLIENT_SENT);
213} 188}
214 189
215 190
222void 197void
223esrv_draw_look (object *pl) 198esrv_draw_look (object *pl)
224{ 199{
225 object *tmp, *last; 200 object *tmp, *last;
226 int got_one = 0, start_look = 0, end_look = 0; 201 int got_one = 0, start_look = 0, end_look = 0;
227 SockList sl;
228 char buf[MAX_BUF]; 202 char buf[MAX_BUF];
229 203
230 if (!pl->contr->socket.update_look) 204 if (!pl->contr->socket.update_look)
231 { 205 {
232 LOG (llevDebug, "esrv_draw_look called when update_look was not set\n"); 206 LOG (llevDebug, "esrv_draw_look called when update_look was not set\n");
233 return; 207 return;
234 } 208 }
235 else 209 else
236 {
237 pl->contr->socket.update_look = 0; 210 pl->contr->socket.update_look = 0;
238 }
239 211
240 if (QUERY_FLAG (pl, FLAG_REMOVED) || pl->map == NULL || pl->map->in_memory != MAP_IN_MEMORY || out_of_map (pl->map, pl->x, pl->y)) 212 if (QUERY_FLAG (pl, FLAG_REMOVED)
213 || !pl->map
214 || pl->map->in_memory != MAP_IN_MEMORY
215 || out_of_map (pl->map, pl->x, pl->y))
241 return; 216 return;
242 217
243 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp && tmp->above; tmp = tmp->above); 218 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp && tmp->above; tmp = tmp->above)
219 ;
244 220
245 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 221 packet sl;
246 222
247 Write_String_To_Socket (&pl->contr->socket, "delinv 0", strlen ("delinv 0")); 223 pl->contr->socket.send_packet ("delinv 0");
224
248 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 225 sl.printf ("item%d ", pl->contr->socket.itemcmd);
249 sl.len = strlen ((char *) sl.buf);
250 226
251 SockList_AddInt (&sl, 0); 227 sl << uint32 (0);
252 228
253 if (!(pl->contr->socket.faces_sent[empty_face->number] & NS_FACESENT_FACE)) 229 if (!(pl->contr->socket.faces_sent[empty_face->number] & NS_FACESENT_FACE))
254 esrv_send_face (&pl->contr->socket, empty_face->number, 0); 230 esrv_send_face (&pl->contr->socket, empty_face->number, 0);
255 231
256 if (pl->contr->socket.look_position) 232 if (pl->contr->socket.look_position)
257 { 233 {
258 SockList_AddInt (&sl, 0x80000000 | (pl->contr->socket.look_position - NUM_LOOK_OBJECTS)); 234 sl << uint32 (0x80000000 | (pl->contr->socket.look_position - NUM_LOOK_OBJECTS))
259 SockList_AddInt (&sl, 0); 235 << uint32 (0)
260 SockList_AddInt (&sl, (uint32) - 1); 236 << sint32 (-1)
261 SockList_AddInt (&sl, empty_face->number); 237 << uint32 (empty_face->number);
238
262 sprintf (buf, "Click here to see %d previous items", NUM_LOOK_OBJECTS); 239 sl.printf ("Click here to see %d previous items", NUM_LOOK_OBJECTS);
263 add_stringlen_to_sockbuf (buf, &sl); 240
264 SockList_AddShort (&sl, 0); 241 sl << uint16 (0)
265 SockList_AddChar (&sl, 0); 242 << uint8 (0)
266 SockList_AddInt (&sl, 0); 243 << uint32 (0);
244
267 if (pl->contr->socket.itemcmd == 2) 245 if (pl->contr->socket.itemcmd == 2)
268 SockList_AddShort (&sl, 0); 246 sl << uint16 (0);
269 } 247 }
270 248
271 for (last = NULL; tmp != last; tmp = tmp->below) 249 for (last = NULL; tmp != last; tmp = tmp->below)
272 { 250 {
273 object *head; 251 object *head;
276 { 254 {
277 last = tmp->below; /* assumes double floor mode */ 255 last = tmp->below; /* assumes double floor mode */
278 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR)) 256 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR))
279 last = last->below; 257 last = last->below;
280 } 258 }
259
281 if (LOOK_OBJ (tmp)) 260 if (LOOK_OBJ (tmp))
282 { 261 {
283 if (++start_look < pl->contr->socket.look_position) 262 if (++start_look < pl->contr->socket.look_position)
284 continue; 263 continue;
264
285 end_look++; 265 end_look++;
266
286 if (end_look > NUM_LOOK_OBJECTS) 267 if (end_look > NUM_LOOK_OBJECTS)
287 { 268 {
288 /* What we basically do is make a 'fake' object - when the user applies it, 269 /* What we basically do is make a 'fake' object - when the user applies it,
289 * we notice the special tag the object has, and act accordingly. 270 * we notice the special tag the object has, and act accordingly.
290 */ 271 */
291 SockList_AddInt (&sl, 0x80000000 | (pl->contr->socket.look_position + NUM_LOOK_OBJECTS)); 272 sl << uint32 (0x80000000 | (pl->contr->socket.look_position + NUM_LOOK_OBJECTS))
292 SockList_AddInt (&sl, 0); 273 << uint32 (0)
293 SockList_AddInt (&sl, (uint32) - 1); 274 << uint32 ((uint32) - 1)
294 SockList_AddInt (&sl, empty_face->number); 275 << uint32 (empty_face->number);
276
295 sprintf (buf, "Click here to see next group of items"); 277 sl.printf ("Click here to see next group of items");
296 add_stringlen_to_sockbuf (buf, &sl); 278
297 SockList_AddShort (&sl, 0); 279 sl << uint16 (0)
298 SockList_AddChar (&sl, 0); 280 << uint8 (0)
299 SockList_AddInt (&sl, 0); 281 << uint32 (0);
282
300 if (pl->contr->socket.itemcmd == 2) 283 if (pl->contr->socket.itemcmd == 2)
301 SockList_AddShort (&sl, 0); 284 sl << uint16 (0);
285
302 break; 286 break;
303 } 287 }
288
304 if (tmp->head) 289 if (tmp->head)
305 head = tmp->head; 290 head = tmp->head;
306 else 291 else
307 head = tmp; 292 head = tmp;
308 293
309 add_object_to_socklist (&pl->contr->socket, &sl, head); 294 add_object_to_socklist (pl->contr->socket, sl, head);
310 got_one++; 295 got_one++;
311 296
312 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN)) 297 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN))
313 { 298 {
314 Send_With_Handling (&pl->contr->socket, &sl); 299 Send_With_Handling (&pl->contr->socket, &sl);
300
301 sl.reset ();
315 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 302 sl.printf ("item%d ", pl->contr->socket.itemcmd);
316 sl.len = strlen ((char *) sl.buf); 303 sl << uint32 (0);
317 SockList_AddInt (&sl, 0);
318 got_one = 0; 304 got_one = 0;
319 } 305 }
320 } /* If LOOK_OBJ() */ 306 } /* If LOOK_OBJ() */
321 } 307 }
308
322 if (got_one) 309 if (got_one)
323 Send_With_Handling (&pl->contr->socket, &sl); 310 Send_With_Handling (&pl->contr->socket, &sl);
324 311
325 free (sl.buf);
326} 312}
327 313
328/** 314/**
329 * Sends whole inventory. 315 * Sends whole inventory.
330 */ 316 */
331void 317void
332esrv_send_inventory (object *pl, object *op) 318esrv_send_inventory (object *pl, object *op)
333{ 319{
334 object *tmp; 320 object *tmp;
335 int got_one = 0; 321 int got_one = 0;
336 SockList sl;
337 322
338 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 323 packet sl;
339 324
340 sprintf ((char *) sl.buf, "delinv %d", op->count); 325 sl.printf ("delinv %d", op->count);
341 sl.len = strlen ((char *) sl.buf);
342 Send_With_Handling (&pl->contr->socket, &sl); 326 Send_With_Handling (&pl->contr->socket, &sl);
343 327
328 sl.reset ();
344 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 329 sl.printf ("item%d ", pl->contr->socket.itemcmd);
345 sl.len = strlen ((char *) sl.buf);
346 330
347 SockList_AddInt (&sl, op->count); 331 sl << uint32 (op->count);
348 332
349 for (tmp = op->inv; tmp; tmp = tmp->below) 333 for (tmp = op->inv; tmp; tmp = tmp->below)
350 { 334 {
351 object *head; 335 object *head;
352 336
355 else 339 else
356 head = tmp; 340 head = tmp;
357 341
358 if (LOOK_OBJ (head)) 342 if (LOOK_OBJ (head))
359 { 343 {
360 add_object_to_socklist (&pl->contr->socket, &sl, head); 344 add_object_to_socklist (pl->contr->socket, sl, head);
361 345
362 got_one++; 346 got_one++;
363 347
364 /* IT is possible for players to accumulate a huge amount of 348 /* IT is possible for players to accumulate a huge amount of
365 * items (especially with some of the bags out there) to 349 * items (especially with some of the bags out there) to
368 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN)) 352 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN))
369 { 353 {
370 Send_With_Handling (&pl->contr->socket, &sl); 354 Send_With_Handling (&pl->contr->socket, &sl);
371 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 355 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd);
372 sl.len = strlen ((char *) sl.buf); 356 sl.len = strlen ((char *) sl.buf);
373 SockList_AddInt (&sl, op->count); 357 sl << uint32 (op->count);
374 got_one = 0; 358 got_one = 0;
375 } 359 }
376 } /* If LOOK_OBJ() */ 360 } /* If LOOK_OBJ() */
377 } 361 }
362
378 if (got_one) 363 if (got_one)
379 Send_With_Handling (&pl->contr->socket, &sl); 364 Send_With_Handling (&pl->contr->socket, &sl);
380 free (sl.buf); 365
381} 366}
382 367
383/** 368/**
384 * Updates object *op for player *pl. 369 * Updates object *op for player *pl.
385 * 370 *
389 */ 374 */
390 375
391void 376void
392esrv_update_item (int flags, object *pl, object *op) 377esrv_update_item (int flags, object *pl, object *op)
393{ 378{
394 SockList sl;
395
396 /* If we have a request to send the player item, skip a few checks. */ 379 /* If we have a request to send the player item, skip a few checks. */
397 if (op != pl) 380 if (op != pl)
398 { 381 {
399 if (!LOOK_OBJ (op)) 382 if (!LOOK_OBJ (op))
400 return; 383 return;
401 /* we remove the check for op->env, because in theory, the object 384 /* we remove the check for op->env, because in theory, the object
402 * is hopefully in the same place, so the client should preserve 385 * is hopefully in the same place, so the client should preserve
403 * order. 386 * order.
404 */ 387 */
405 } 388 }
389
406 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT)) 390 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT))
407 { 391 {
408 /* FLAG_CLIENT_SENT is debug only. We are using it to see where 392 /* FLAG_CLIENT_SENT is debug only. We are using it to see where
409 * this is happening - we can set a breakpoint here in the debugger 393 * this is happening - we can set a breakpoint here in the debugger
410 * and track back the call. 394 * and track back the call.
411 */ 395 */
412 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count); 396 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count);
413 } 397 }
414 sl.buf = (unsigned char *) malloc (MAXSOCKBUF);
415 398
416 strcpy ((char *) sl.buf, "upditem "); 399 packet sl;
417 sl.len = strlen ((char *) sl.buf);
418 400
419 SockList_AddChar (&sl, (char) flags); 401 sl << "upditem "
402 << uint8 (flags);
420 403
421 if (op->head) 404 if (op->head)
422 op = op->head; 405 op = op->head;
423 406
424 SockList_AddInt (&sl, op->count); 407 sl << uint32 (op->count);
425 408
426 if (flags & UPD_LOCATION) 409 if (flags & UPD_LOCATION)
427 SockList_AddInt (&sl, op->env ? op->env->count : 0); 410 sl << uint32 (op->env ? op->env->count : 0);
428 411
429 if (flags & UPD_FLAGS) 412 if (flags & UPD_FLAGS)
430 SockList_AddInt (&sl, query_flags (op)); 413 sl << uint32 (query_flags (op));
431 414
432 if (flags & UPD_WEIGHT) 415 if (flags & UPD_WEIGHT)
433 { 416 {
434 sint32 weight = WEIGHT (op); 417 sint32 weight = WEIGHT (op);
435 418
436 SockList_AddInt (&sl, QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight); 419 sl << uint32 (QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight);
420
437 if (pl == op) 421 if (pl == op)
438 {
439 op->contr->last_weight = weight; 422 op->contr->last_weight = weight;
440 }
441 } 423 }
442 424
443 if (flags & UPD_FACE) 425 if (flags & UPD_FACE)
444 { 426 {
445 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE)) 427 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE))
446 esrv_send_face (&pl->contr->socket, op->face->number, 0); 428 esrv_send_face (&pl->contr->socket, op->face->number, 0);
447 SockList_AddInt (&sl, op->face->number); 429
430 sl << uint32 (op->face->number);
448 } 431 }
432
449 if (flags & UPD_NAME) 433 if (flags & UPD_NAME)
450 { 434 {
451 int len; 435 int len;
452 const char *item_p; 436 const char *item_p;
453 char item_n[MAX_BUF]; 437 char item_n[MAX_BUF];
468 } 452 }
469 453
470 strncpy (item_n + len + 1, item_p, 127); 454 strncpy (item_n + len + 1, item_p, 127);
471 item_n[254] = 0; 455 item_n[254] = 0;
472 len += strlen (item_n + 1 + len) + 1; 456 len += strlen (item_n + 1 + len) + 1;
473 SockList_AddChar (&sl, (char) len); 457
474 memcpy (sl.buf + sl.len, item_n, len); 458 sl << data8 (item_n, len);
475 sl.len += len;
476 } 459 }
460
477 if (flags & UPD_ANIM) 461 if (flags & UPD_ANIM)
478 SockList_AddShort (&sl, op->animation_id); 462 sl << uint16 (op->animation_id);
479 463
480 if (flags & UPD_ANIMSPEED) 464 if (flags & UPD_ANIMSPEED)
481 { 465 {
482 int anim_speed = 0; 466 int anim_speed = 0;
483 467
492 else if (FABS (op->speed) >= 1.0) 476 else if (FABS (op->speed) >= 1.0)
493 anim_speed = 1; 477 anim_speed = 1;
494 else 478 else
495 anim_speed = (int) (1.0 / FABS (op->speed)); 479 anim_speed = (int) (1.0 / FABS (op->speed));
496 } 480 }
481
497 if (anim_speed > 255) 482 if (anim_speed > 255)
498 anim_speed = 255; 483 anim_speed = 255;
499 } 484 }
500 SockList_AddChar (&sl, (char) anim_speed); 485
486 sl << uint8 (anim_speed);
501 } 487 }
488
502 if (flags & UPD_NROF) 489 if (flags & UPD_NROF)
503 SockList_AddInt (&sl, op->nrof); 490 sl << uint32 (op->nrof);
504 491
505 Send_With_Handling (&pl->contr->socket, &sl); 492 Send_With_Handling (&pl->contr->socket, &sl);
506 free (sl.buf);
507} 493}
508 494
509/** 495/**
510 * Sends item's info to player. 496 * Sends item's info to player.
511 */ 497 */
512void 498void
513esrv_send_item (object *pl, object *op) 499esrv_send_item (object *pl, object *op)
514{ 500{
515 SockList sl;
516
517 /* If this is not the player object, do some more checks */ 501 /* If this is not the player object, do some more checks */
518 if (op != pl) 502 if (op != pl)
519 { 503 {
520 /* We only send 'visibile' objects to the client */ 504 /* We only send 'visibile' objects to the client */
521 if (!LOOK_OBJ (op)) 505 if (!LOOK_OBJ (op))
528 pl->contr->socket.update_look = 1; 512 pl->contr->socket.update_look = 1;
529 return; 513 return;
530 } 514 }
531 } 515 }
532 516
533 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 517 packet sl;
534 518
535 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 519 sl.printf ("item%d ", pl->contr->socket.itemcmd);
536 sl.len = strlen ((char *) sl.buf);
537 520
538 if (op->head) 521 if (op->head)
539 op = op->head; 522 op = op->head;
540 523
541 SockList_AddInt (&sl, op->env ? op->env->count : 0); 524 sl << uint32 (op->env ? op->env->count : 0);
542 525
543 add_object_to_socklist (&pl->contr->socket, &sl, op); 526 add_object_to_socklist (pl->contr->socket, sl, op);
544 527
545 Send_With_Handling (&pl->contr->socket, &sl); 528 Send_With_Handling (&pl->contr->socket, &sl);
546 SET_FLAG (op, FLAG_CLIENT_SENT); 529 SET_FLAG (op, FLAG_CLIENT_SENT);
547 free (sl.buf); 530
548} 531}
549 532
550/** 533/**
551 * Tells the client to delete an item. Uses the item 534 * Tells the client to delete an item. Uses the item
552 * command with a -1 location. 535 * command with a -1 location.
553 */ 536 */
554 537
555void 538void
556esrv_del_item (player *pl, int tag) 539esrv_del_item (player *pl, int tag)
557{ 540{
558 SockList sl; 541 packet sl;
559 542
560 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 543 sl << "delitem "
561 544 << uint32 (tag);
562 strcpy ((char *) sl.buf, "delitem ");
563 sl.len = strlen ((char *) sl.buf);
564 SockList_AddInt (&sl, tag);
565 545
566 Send_With_Handling (&pl->socket, &sl); 546 Send_With_Handling (&pl->socket, &sl);
567 free (sl.buf);
568} 547}
569 548
570 549
571/******************************************************************************* 550/*******************************************************************************
572 * 551 *
611 590
612/** Client wants to examine some object. So lets do so. */ 591/** Client wants to examine some object. So lets do so. */
613void 592void
614ExamineCmd (char *buf, int len, player *pl) 593ExamineCmd (char *buf, int len, player *pl)
615{ 594{
616 long tag = atoi (buf); 595 tag_t tag = atoi (buf);
596
597 /* If the high bit is set, player examined a pseudo object. */
598 if (tag & 0x80000000)
599 return;
600
617 object *op = esrv_get_ob_from_count (pl->ob, tag); 601 object *op = esrv_get_ob_from_count (pl->ob, tag);
618 602
619 if (!op) 603 if (!op)
620 { 604 {
621 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag); 605 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag);
622 return; 606 return;
623 } 607 }
608
624 examine (pl->ob, op); 609 examine (pl->ob, op);
625} 610}
626 611
627/** Client wants to apply some object. Lets do so. */ 612/** Client wants to apply some object. Lets do so. */
628void 613void
629ApplyCmd (char *buf, int len, player *pl) 614ApplyCmd (char *buf, int len, player *pl)
630{ 615{
631 uint32 tag = atoi (buf); 616 tag_t tag = atoi (buf);
632 object *op = esrv_get_ob_from_count (pl->ob, tag);
633 617
634 /* sort of a hack, but if the player saves and the player then manually 618 /* sort of a hack, but if the player saves and the player then manually
635 * applies a savebed (or otherwise tries to do stuff), we run into trouble. 619 * applies a savebed (or otherwise tries to do stuff), we run into trouble.
636 */ 620 */
637 if (QUERY_FLAG (pl->ob, FLAG_REMOVED)) 621 if (QUERY_FLAG (pl->ob, FLAG_REMOVED))
643 pl->socket.look_position = tag & 0x7fffffff; 627 pl->socket.look_position = tag & 0x7fffffff;
644 pl->socket.update_look = 1; 628 pl->socket.update_look = 1;
645 return; 629 return;
646 } 630 }
647 631
632 object *op = esrv_get_ob_from_count (pl->ob, tag);
633
648 if (!op) 634 if (!op)
649 { 635 {
650 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag); 636 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag);
651 return; 637 return;
652 } 638 }
639
653 player_apply (pl->ob, op, 0, 0); 640 player_apply (pl->ob, op, 0, 0);
654} 641}
655 642
656/** Client wants to apply some object. Lets do so. */ 643/** Client wants to apply some object. Lets do so. */
657void 644void
658LockItem (uint8 * data, int len, player *pl) 645LockItem (uint8 *data, int len, player *pl)
659{ 646{
660 int flag, tag;
661 object *op;
662
663 flag = data[0]; 647 int flag = data[0];
664 tag = GetInt_String (data + 1); 648 tag_t tag = net_uint32 (data + 1);
665 op = esrv_get_ob_from_count (pl->ob, tag); 649 object *op = esrv_get_ob_from_count (pl->ob, tag);
666 650
667 if (!op) 651 if (!op)
668 { 652 {
669 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock"); 653 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock");
670 return; 654 return;
671 } 655 }
656
672 if (!flag) 657 if (!flag)
673 CLEAR_FLAG (op, FLAG_INV_LOCKED); 658 CLEAR_FLAG (op, FLAG_INV_LOCKED);
674 else 659 else
675 SET_FLAG (op, FLAG_INV_LOCKED); 660 SET_FLAG (op, FLAG_INV_LOCKED);
661
676 esrv_update_item (UPD_FLAGS, pl->ob, op); 662 esrv_update_item (UPD_FLAGS, pl->ob, op);
677} 663}
678 664
679/** Client wants to apply some object. Lets do so. */ 665/** Client wants to apply some object. Lets do so. */
680void 666void
681MarkItem (uint8 * data, int len, player *pl) 667MarkItem (uint8 * data, int len, player *pl)
682{ 668{
683 int tag; 669 tag_t tag = net_uint32 (data);
684 object *op;
685
686 tag = GetInt_String (data);
687 op = esrv_get_ob_from_count (pl->ob, tag); 670 object *op = esrv_get_ob_from_count (pl->ob, tag);
671
688 if (!op) 672 if (!op)
689 { 673 {
690 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark"); 674 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark");
691 return; 675 return;
692 } 676 }
677
693 pl->mark = op; 678 pl->mark = op;
694 pl->mark_count = op->count;
695 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op)); 679 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op));
696} 680}
697
698 681
699/** 682/**
700 * look_at prints items on the specified square. 683 * look_at prints items on the specified square.
701 * 684 *
702 * [ removed EARTHWALL check and added check for containers inventory. 685 * [ removed EARTHWALL check and added check for containers inventory.
706look_at (object *op, int dx, int dy) 689look_at (object *op, int dx, int dy)
707{ 690{
708 object *tmp; 691 object *tmp;
709 int flag = 0; 692 int flag = 0;
710 sint16 x, y; 693 sint16 x, y;
711 mapstruct *m; 694 maptile *m;
712 695
713 x = op->x + dx; 696 x = op->x + dx;
714 y = op->y + dy; 697 y = op->y + dy;
715 698
716 if (out_of_map (op->map, x, y)) 699 if (out_of_map (op->map, x, y))
799 return; 782 return;
800 } 783 }
801 784
802 if (!to) 785 if (!to)
803 { /* drop it to the ground */ 786 { /* drop it to the ground */
804
805/* LOG(llevDebug, "Drop it on the ground.\n");*/
806
807 if (op->map && !op->env) 787 if (op->map && !op->env)
808 {
809
810/* LOG(llevDebug,"Dropping object to ground that is already on ground\n");*/
811 return; 788 return;
812 } 789
813 /* If it is an active container, then we should drop all objects 790 /* If it is an active container, then we should drop all objects
814 * in the container and not the container itself. 791 * in the container and not the container itself.
815 */ 792 */
816 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED)) 793 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED))
817 { 794 {
820 for (current = op->inv; current != NULL; current = next) 797 for (current = op->inv; current != NULL; current = next)
821 { 798 {
822 next = current->below; 799 next = current->below;
823 drop_object (pl, current, 0); 800 drop_object (pl, current, 0);
824 } 801 }
802
825 esrv_update_item (UPD_WEIGHT, pl, op); 803 esrv_update_item (UPD_WEIGHT, pl, op);
826 } 804 }
827 else 805 else
828 { 806 {
829 drop_object (pl, op, nrof); 807 drop_object (pl, op, nrof);
838 816
839 pl->contr->count = nrof; 817 pl->contr->count = nrof;
840 pick_up (pl, op); 818 pick_up (pl, op);
841 return; 819 return;
842 } 820 }
821
843 env = esrv_get_ob_from_count (pl, to); 822 env = esrv_get_ob_from_count (pl, to);
844 if (!env) 823 if (!env)
845 { 824 {
846 LOG (llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to); 825 LOG (llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to);
847 return; 826 return;
848 } 827 }
828
849 /* put_object_in_sack presumes that necessary sanity checking 829 /* put_object_in_sack presumes that necessary sanity checking
850 * has already been done (eg, it can be picked up and fits in 830 * has already been done (eg, it can be picked up and fits in
851 * in a sack, so check for those things. We should also check 831 * in a sack, so check for those things. We should also check
852 * an make sure env is in fact a container for that matter. 832 * an make sure env is in fact a container for that matter.
853 */ 833 */
854 if (env->type == CONTAINER && can_pick (pl, op) && sack_can_hold (pl, env, op, nrof)) 834 if (env->type == CONTAINER && can_pick (pl, op) && sack_can_hold (pl, env, op, nrof))
855 { 835 {
856 put_object_in_sack (pl, env, op, nrof); 836 put_object_in_sack (pl, env, op, nrof);
857 } 837 }
858} 838}
839

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines