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.14 by root, Thu Dec 14 00:23:59 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 */
141/* Used in the send_look to put object head into SockList 114/* Used in the send_look to put object head into SockList
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, SockList &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 SockList sl (MAXSOCKBUF);
246 222
247 Write_String_To_Socket (&pl->contr->socket, "delinv 0", strlen ("delinv 0")); 223 Write_String_To_Socket (&pl->contr->socket, "delinv 0", sizeof ("delinv 0") - 1);
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); 312 sl.free ();
326} 313}
327 314
328/** 315/**
329 * Sends whole inventory. 316 * Sends whole inventory.
330 */ 317 */
331void 318void
332esrv_send_inventory (object *pl, object *op) 319esrv_send_inventory (object *pl, object *op)
333{ 320{
334 object *tmp; 321 object *tmp;
335 int got_one = 0; 322 int got_one = 0;
336 SockList sl;
337 323
338 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 324 SockList sl (MAXSOCKBUF);
339 325
340 sprintf ((char *) sl.buf, "delinv %d", op->count); 326 sl.printf ("delinv %d", op->count);
341 sl.len = strlen ((char *) sl.buf);
342 Send_With_Handling (&pl->contr->socket, &sl); 327 Send_With_Handling (&pl->contr->socket, &sl);
343 328
329 sl.reset ();
344 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 330 sl.printf ("item%d ", pl->contr->socket.itemcmd);
345 sl.len = strlen ((char *) sl.buf);
346 331
347 SockList_AddInt (&sl, op->count); 332 sl << uint32 (op->count);
348 333
349 for (tmp = op->inv; tmp; tmp = tmp->below) 334 for (tmp = op->inv; tmp; tmp = tmp->below)
350 { 335 {
351 object *head; 336 object *head;
352 337
355 else 340 else
356 head = tmp; 341 head = tmp;
357 342
358 if (LOOK_OBJ (head)) 343 if (LOOK_OBJ (head))
359 { 344 {
360 add_object_to_socklist (&pl->contr->socket, &sl, head); 345 add_object_to_socklist (pl->contr->socket, sl, head);
361 346
362 got_one++; 347 got_one++;
363 348
364 /* IT is possible for players to accumulate a huge amount of 349 /* IT is possible for players to accumulate a huge amount of
365 * items (especially with some of the bags out there) to 350 * items (especially with some of the bags out there) to
368 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN)) 353 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN))
369 { 354 {
370 Send_With_Handling (&pl->contr->socket, &sl); 355 Send_With_Handling (&pl->contr->socket, &sl);
371 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 356 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd);
372 sl.len = strlen ((char *) sl.buf); 357 sl.len = strlen ((char *) sl.buf);
373 SockList_AddInt (&sl, op->count); 358 sl << uint32 (op->count);
374 got_one = 0; 359 got_one = 0;
375 } 360 }
376 } /* If LOOK_OBJ() */ 361 } /* If LOOK_OBJ() */
377 } 362 }
363
378 if (got_one) 364 if (got_one)
379 Send_With_Handling (&pl->contr->socket, &sl); 365 Send_With_Handling (&pl->contr->socket, &sl);
380 free (sl.buf); 366
367 sl.free ();
381} 368}
382 369
383/** 370/**
384 * Updates object *op for player *pl. 371 * Updates object *op for player *pl.
385 * 372 *
389 */ 376 */
390 377
391void 378void
392esrv_update_item (int flags, object *pl, object *op) 379esrv_update_item (int flags, object *pl, object *op)
393{ 380{
394 SockList sl;
395
396 /* If we have a request to send the player item, skip a few checks. */ 381 /* If we have a request to send the player item, skip a few checks. */
397 if (op != pl) 382 if (op != pl)
398 { 383 {
399 if (!LOOK_OBJ (op)) 384 if (!LOOK_OBJ (op))
400 return; 385 return;
401 /* we remove the check for op->env, because in theory, the object 386 /* we remove the check for op->env, because in theory, the object
402 * is hopefully in the same place, so the client should preserve 387 * is hopefully in the same place, so the client should preserve
403 * order. 388 * order.
404 */ 389 */
405 } 390 }
391
406 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT)) 392 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT))
407 { 393 {
408 /* FLAG_CLIENT_SENT is debug only. We are using it to see where 394 /* 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 395 * this is happening - we can set a breakpoint here in the debugger
410 * and track back the call. 396 * and track back the call.
411 */ 397 */
412 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count); 398 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count);
413 } 399 }
414 sl.buf = (unsigned char *) malloc (MAXSOCKBUF);
415 400
416 strcpy ((char *) sl.buf, "upditem "); 401 SockList sl (MAXSOCKBUF);
417 sl.len = strlen ((char *) sl.buf);
418 402
419 SockList_AddChar (&sl, (char) flags); 403 sl << "upditem "
404 << uint8 (flags);
420 405
421 if (op->head) 406 if (op->head)
422 op = op->head; 407 op = op->head;
423 408
424 SockList_AddInt (&sl, op->count); 409 sl << uint32 (op->count);
425 410
426 if (flags & UPD_LOCATION) 411 if (flags & UPD_LOCATION)
427 SockList_AddInt (&sl, op->env ? op->env->count : 0); 412 sl << uint32 (op->env ? op->env->count : 0);
428 413
429 if (flags & UPD_FLAGS) 414 if (flags & UPD_FLAGS)
430 SockList_AddInt (&sl, query_flags (op)); 415 sl << uint32 (query_flags (op));
431 416
432 if (flags & UPD_WEIGHT) 417 if (flags & UPD_WEIGHT)
433 { 418 {
434 sint32 weight = WEIGHT (op); 419 sint32 weight = WEIGHT (op);
435 420
436 SockList_AddInt (&sl, QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight); 421 sl << uint32 (QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight);
422
437 if (pl == op) 423 if (pl == op)
438 {
439 op->contr->last_weight = weight; 424 op->contr->last_weight = weight;
440 }
441 } 425 }
442 426
443 if (flags & UPD_FACE) 427 if (flags & UPD_FACE)
444 { 428 {
445 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE)) 429 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE))
446 esrv_send_face (&pl->contr->socket, op->face->number, 0); 430 esrv_send_face (&pl->contr->socket, op->face->number, 0);
447 SockList_AddInt (&sl, op->face->number); 431
432 sl << uint32 (op->face->number);
448 } 433 }
434
449 if (flags & UPD_NAME) 435 if (flags & UPD_NAME)
450 { 436 {
451 int len; 437 int len;
452 const char *item_p; 438 const char *item_p;
453 char item_n[MAX_BUF]; 439 char item_n[MAX_BUF];
468 } 454 }
469 455
470 strncpy (item_n + len + 1, item_p, 127); 456 strncpy (item_n + len + 1, item_p, 127);
471 item_n[254] = 0; 457 item_n[254] = 0;
472 len += strlen (item_n + 1 + len) + 1; 458 len += strlen (item_n + 1 + len) + 1;
473 SockList_AddChar (&sl, (char) len); 459
474 memcpy (sl.buf + sl.len, item_n, len); 460 sl << data8 (item_n, len);
475 sl.len += len;
476 } 461 }
462
477 if (flags & UPD_ANIM) 463 if (flags & UPD_ANIM)
478 SockList_AddShort (&sl, op->animation_id); 464 sl << uint16 (op->animation_id);
479 465
480 if (flags & UPD_ANIMSPEED) 466 if (flags & UPD_ANIMSPEED)
481 { 467 {
482 int anim_speed = 0; 468 int anim_speed = 0;
483 469
492 else if (FABS (op->speed) >= 1.0) 478 else if (FABS (op->speed) >= 1.0)
493 anim_speed = 1; 479 anim_speed = 1;
494 else 480 else
495 anim_speed = (int) (1.0 / FABS (op->speed)); 481 anim_speed = (int) (1.0 / FABS (op->speed));
496 } 482 }
483
497 if (anim_speed > 255) 484 if (anim_speed > 255)
498 anim_speed = 255; 485 anim_speed = 255;
499 } 486 }
500 SockList_AddChar (&sl, (char) anim_speed); 487
488 sl << uint8 (anim_speed);
501 } 489 }
490
502 if (flags & UPD_NROF) 491 if (flags & UPD_NROF)
503 SockList_AddInt (&sl, op->nrof); 492 sl << uint32 (op->nrof);
504 493
505 Send_With_Handling (&pl->contr->socket, &sl); 494 Send_With_Handling (&pl->contr->socket, &sl);
506 free (sl.buf); 495 sl.free ();
507} 496}
508 497
509/** 498/**
510 * Sends item's info to player. 499 * Sends item's info to player.
511 */ 500 */
512void 501void
513esrv_send_item (object *pl, object *op) 502esrv_send_item (object *pl, object *op)
514{ 503{
515 SockList sl;
516
517 /* If this is not the player object, do some more checks */ 504 /* If this is not the player object, do some more checks */
518 if (op != pl) 505 if (op != pl)
519 { 506 {
520 /* We only send 'visibile' objects to the client */ 507 /* We only send 'visibile' objects to the client */
521 if (!LOOK_OBJ (op)) 508 if (!LOOK_OBJ (op))
528 pl->contr->socket.update_look = 1; 515 pl->contr->socket.update_look = 1;
529 return; 516 return;
530 } 517 }
531 } 518 }
532 519
533 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 520 SockList sl (MAXSOCKBUF);
534 521
535 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 522 sl.printf ("item%d ", pl->contr->socket.itemcmd);
536 sl.len = strlen ((char *) sl.buf);
537 523
538 if (op->head) 524 if (op->head)
539 op = op->head; 525 op = op->head;
540 526
541 SockList_AddInt (&sl, op->env ? op->env->count : 0); 527 sl << uint32 (op->env ? op->env->count : 0);
542 528
543 add_object_to_socklist (&pl->contr->socket, &sl, op); 529 add_object_to_socklist (pl->contr->socket, sl, op);
544 530
545 Send_With_Handling (&pl->contr->socket, &sl); 531 Send_With_Handling (&pl->contr->socket, &sl);
546 SET_FLAG (op, FLAG_CLIENT_SENT); 532 SET_FLAG (op, FLAG_CLIENT_SENT);
547 free (sl.buf); 533
534 sl.free ();
548} 535}
549 536
550/** 537/**
551 * Tells the client to delete an item. Uses the item 538 * Tells the client to delete an item. Uses the item
552 * command with a -1 location. 539 * command with a -1 location.
553 */ 540 */
554 541
555void 542void
556esrv_del_item (player *pl, int tag) 543esrv_del_item (player *pl, int tag)
557{ 544{
558 SockList sl; 545 SockList sl (MAXSOCKBUF);
559 546
560 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 547 sl << "delitem "
561 548 << uint32 (tag);
562 strcpy ((char *) sl.buf, "delitem ");
563 sl.len = strlen ((char *) sl.buf);
564 SockList_AddInt (&sl, tag);
565 549
566 Send_With_Handling (&pl->socket, &sl); 550 Send_With_Handling (&pl->socket, &sl);
567 free (sl.buf); 551 sl.free ();
568} 552}
569 553
570 554
571/******************************************************************************* 555/*******************************************************************************
572 * 556 *
611 595
612/** Client wants to examine some object. So lets do so. */ 596/** Client wants to examine some object. So lets do so. */
613void 597void
614ExamineCmd (char *buf, int len, player *pl) 598ExamineCmd (char *buf, int len, player *pl)
615{ 599{
616 long tag = atoi (buf); 600 tag_t tag = atoi (buf);
601
602 /* If the high bit is set, player examined a pseudo object. */
603 if (tag & 0x80000000)
604 return;
605
617 object *op = esrv_get_ob_from_count (pl->ob, tag); 606 object *op = esrv_get_ob_from_count (pl->ob, tag);
618 607
619 if (!op) 608 if (!op)
620 { 609 {
621 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag); 610 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag);
622 return; 611 return;
623 } 612 }
613
624 examine (pl->ob, op); 614 examine (pl->ob, op);
625} 615}
626 616
627/** Client wants to apply some object. Lets do so. */ 617/** Client wants to apply some object. Lets do so. */
628void 618void
629ApplyCmd (char *buf, int len, player *pl) 619ApplyCmd (char *buf, int len, player *pl)
630{ 620{
631 uint32 tag = atoi (buf); 621 tag_t tag = atoi (buf);
632 object *op = esrv_get_ob_from_count (pl->ob, tag);
633 622
634 /* sort of a hack, but if the player saves and the player then manually 623 /* 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. 624 * applies a savebed (or otherwise tries to do stuff), we run into trouble.
636 */ 625 */
637 if (QUERY_FLAG (pl->ob, FLAG_REMOVED)) 626 if (QUERY_FLAG (pl->ob, FLAG_REMOVED))
643 pl->socket.look_position = tag & 0x7fffffff; 632 pl->socket.look_position = tag & 0x7fffffff;
644 pl->socket.update_look = 1; 633 pl->socket.update_look = 1;
645 return; 634 return;
646 } 635 }
647 636
637 object *op = esrv_get_ob_from_count (pl->ob, tag);
638
648 if (!op) 639 if (!op)
649 { 640 {
650 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag); 641 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag);
651 return; 642 return;
652 } 643 }
644
653 player_apply (pl->ob, op, 0, 0); 645 player_apply (pl->ob, op, 0, 0);
654} 646}
655 647
656/** Client wants to apply some object. Lets do so. */ 648/** Client wants to apply some object. Lets do so. */
657void 649void
658LockItem (uint8 * data, int len, player *pl) 650LockItem (uint8 *data, int len, player *pl)
659{ 651{
660 int flag, tag;
661 object *op;
662
663 flag = data[0]; 652 int flag = data[0];
664 tag = GetInt_String (data + 1); 653 tag_t tag = net_uint32 (data + 1);
665 op = esrv_get_ob_from_count (pl->ob, tag); 654 object *op = esrv_get_ob_from_count (pl->ob, tag);
666 655
667 if (!op) 656 if (!op)
668 { 657 {
669 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock"); 658 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock");
670 return; 659 return;
671 } 660 }
661
672 if (!flag) 662 if (!flag)
673 CLEAR_FLAG (op, FLAG_INV_LOCKED); 663 CLEAR_FLAG (op, FLAG_INV_LOCKED);
674 else 664 else
675 SET_FLAG (op, FLAG_INV_LOCKED); 665 SET_FLAG (op, FLAG_INV_LOCKED);
666
676 esrv_update_item (UPD_FLAGS, pl->ob, op); 667 esrv_update_item (UPD_FLAGS, pl->ob, op);
677} 668}
678 669
679/** Client wants to apply some object. Lets do so. */ 670/** Client wants to apply some object. Lets do so. */
680void 671void
681MarkItem (uint8 * data, int len, player *pl) 672MarkItem (uint8 * data, int len, player *pl)
682{ 673{
683 int tag; 674 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); 675 object *op = esrv_get_ob_from_count (pl->ob, tag);
676
688 if (!op) 677 if (!op)
689 { 678 {
690 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark"); 679 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark");
691 return; 680 return;
692 } 681 }
682
693 pl->mark = op; 683 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)); 684 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op));
696} 685}
697
698 686
699/** 687/**
700 * look_at prints items on the specified square. 688 * look_at prints items on the specified square.
701 * 689 *
702 * [ removed EARTHWALL check and added check for containers inventory. 690 * [ removed EARTHWALL check and added check for containers inventory.
706look_at (object *op, int dx, int dy) 694look_at (object *op, int dx, int dy)
707{ 695{
708 object *tmp; 696 object *tmp;
709 int flag = 0; 697 int flag = 0;
710 sint16 x, y; 698 sint16 x, y;
711 mapstruct *m; 699 maptile *m;
712 700
713 x = op->x + dx; 701 x = op->x + dx;
714 y = op->y + dy; 702 y = op->y + dy;
715 703
716 if (out_of_map (op->map, x, y)) 704 if (out_of_map (op->map, x, y))
799 return; 787 return;
800 } 788 }
801 789
802 if (!to) 790 if (!to)
803 { /* drop it to the ground */ 791 { /* drop it to the ground */
804
805/* LOG(llevDebug, "Drop it on the ground.\n");*/
806
807 if (op->map && !op->env) 792 if (op->map && !op->env)
808 {
809
810/* LOG(llevDebug,"Dropping object to ground that is already on ground\n");*/
811 return; 793 return;
812 } 794
813 /* If it is an active container, then we should drop all objects 795 /* If it is an active container, then we should drop all objects
814 * in the container and not the container itself. 796 * in the container and not the container itself.
815 */ 797 */
816 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED)) 798 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED))
817 { 799 {
820 for (current = op->inv; current != NULL; current = next) 802 for (current = op->inv; current != NULL; current = next)
821 { 803 {
822 next = current->below; 804 next = current->below;
823 drop_object (pl, current, 0); 805 drop_object (pl, current, 0);
824 } 806 }
807
825 esrv_update_item (UPD_WEIGHT, pl, op); 808 esrv_update_item (UPD_WEIGHT, pl, op);
826 } 809 }
827 else 810 else
828 { 811 {
829 drop_object (pl, op, nrof); 812 drop_object (pl, op, nrof);
838 821
839 pl->contr->count = nrof; 822 pl->contr->count = nrof;
840 pick_up (pl, op); 823 pick_up (pl, op);
841 return; 824 return;
842 } 825 }
826
843 env = esrv_get_ob_from_count (pl, to); 827 env = esrv_get_ob_from_count (pl, to);
844 if (!env) 828 if (!env)
845 { 829 {
846 LOG (llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to); 830 LOG (llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to);
847 return; 831 return;
848 } 832 }
833
849 /* put_object_in_sack presumes that necessary sanity checking 834 /* put_object_in_sack presumes that necessary sanity checking
850 * has already been done (eg, it can be picked up and fits in 835 * 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 836 * 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. 837 * an make sure env is in fact a container for that matter.
853 */ 838 */
854 if (env->type == CONTAINER && can_pick (pl, op) && sack_can_hold (pl, env, op, nrof)) 839 if (env->type == CONTAINER && can_pick (pl, op) && sack_can_hold (pl, env, op, nrof))
855 { 840 {
856 put_object_in_sack (pl, env, op, nrof); 841 put_object_in_sack (pl, env, op, nrof);
857 } 842 }
858} 843}
844

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines