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.4 by root, Sun Sep 3 00:18:43 2006 UTC vs.
Revision 1.29 by root, Thu Dec 21 23:37:06 2006 UTC

1
2/*
3 * static char *rcsid_item_c =
4 * "$Id: item.C,v 1.4 2006/09/03 00:18:43 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.
36 * This containes item logic for client/server. It doesn't contain 30 * This containes item logic for client/server. It doesn't contain
37 * the actual commands that send the data, but does contain 31 * the actual commands that send the data, but does contain
38 * the logic for what items should be sent. 32 * the logic for what items should be sent.
39 */ 33 */
40 34
41
42#include <global.h> 35#include <global.h>
43#include <object.h> /* LOOK_OBJ */ 36#include <object.h> /* LOOK_OBJ */
44#include <newclient.h>
45#include <newserver.h>
46#include <sproto.h> 37#include <sproto.h>
47 38
48/** This is the maximum number of bytes we expect any one item to take up */ 39/** This is the maximum number of bytes we expect any one item to take up */
49#define MAXITEMLEN 300 40#define MAXITEMLEN 300
41
42#if 0
43tag_t
44client_container::tag () const
45{
46 switch (type)
47 {
48 case CC_INVENTORY:
49 return ns->pl->count;
50 case CC_MAPSPACE:
51 return 0;
52 case CC_CONTAINER:
53 return env->count;
54 }
55
56 abort ();
57}
58
59void
60client_container::clear ()
61{
62 switch (type)
63 {
64 case CC_INVENTORY:
65 abort ();
66
67 case CC_MAPSPACE:
68 case CC_CONTAINER:
69 ns->send_packet_printf ("delinv %d", tag ());
70 break;
71 }
72
73 for (iterator i = begin (); i != end (); ++i)
74 i->op->seen_by = 0;
75
76 vector< refitem, slice_allocator<refitem> >::clear ();
77}
78
79inline iterator
80client_container::merge_item (iterator i, object *op)
81{
82 if (i != end () && i->op == op)
83 return ++i;
84
85 if (op->seen_by)
86 return; // seen by another entity already
87
88 op->seen_by = this;
89
90 refitem ref;
91 ref.op = op;
92
93 return insert (i, ref);
94}
95
96void
97client_container::update (int offset)
98{
99 iterator i = begin ();
100
101 switch (type)
102 {
103 case CC_INVENTORY:
104 case CC_CONTAINER:
105 {
106 object *env = type == CC_INVENTORY
107 ? ns->pl->ob
108 : this->env;
109
110 // pass 1, erase all objects no longer in container
111 for (iterator j = begin (); j != end (); ++j)
112 if (j->op->env != env)
113 {
114 j->op->seen_by = 0;
115 erase (j);
116 }
117
118 // pass 2 merge items
119 for (object *op = env->inv; op; op = op->below)
120 {
121 if (--offset < 0)
122 i = merge_item (i, op);
123 else if (offset < -FLOORBOX_PAGESIZE)
124 break;
125 }
126 }
127 break;
128
129 case CC_MAPSPACE:
130 {
131 // pass 1, erase all objects no longer on space
132 for (iterator j = begin (); j != end (); ++j)
133 if (j->op->x != x || j->op->y != y || j->op->map != map)
134 {
135 j->op->seen_by = 0;
136 erase (j);
137 }
138
139 // pass 2 merge items
140 for (object *op = GET_MAP_OB (map, x, y); op; op = op->above)
141 {
142 if (--offset < 0)
143 i = merge_item (i, op);
144 else if (offset < -FLOORBOX_PAGESIZE)
145 break;
146 }
147 }
148 break;
149 }
150
151 // pass 3, erase all extra items
152 for (iterator j = i; j != end (); ++j)
153 j->op->seen_by = 0;
154
155 if (i != end ())
156 erase (i, end ());
157}
158
159void
160client_container::set_mapspace (maptile *map, int x, int y)
161{
162 if (type == CC_MAPSPACE
163 && this->map == map
164 && this->x == x
165 && this->y == y)
166 return;
167
168 clear ();
169
170 type = CC_MAPSPACE;
171 this->map = map;
172 this->x = x;
173 this->y = y;
174}
175
176void
177client_container::set_container (object *env)
178{
179}
180#endif
50 181
51/******************************************************************************* 182/*******************************************************************************
52 * 183 *
53 * Functions related to sending object data to the client. 184 * Functions related to sending object data to the client.
54 * 185 *
55 ******************************************************************************/ 186 ******************************************************************************/
56 187
57/** 188/**
58 * Adds string to socklist. 189 * This is a similar to query_name, but returns flags
59 * 190 * to be sent to client.
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 */ 191 */
65inline void add_stringlen_to_sockbuf(const char *buf, SockList *sl) 192unsigned int
66{
67 int len;
68
69 len=strlen(buf);
70 if (len>255) len=255;
71 SockList_AddChar(sl, (char) len);
72 strncpy((char*)sl->buf+sl->len, buf,len);
73 sl->len += len;
74}
75
76/**
77 * This is a similar to query_name, but returns flags
78 * to be sended to client.
79 */
80unsigned int query_flags (object *op) 193query_flags (object *op)
81{ 194{
82 unsigned int flags = 0; 195 unsigned int flags = 0;
83 196
84 if(QUERY_FLAG(op,FLAG_APPLIED)) { 197 if (QUERY_FLAG (op, FLAG_APPLIED))
198 {
85 switch(op->type) { 199 switch (op->type)
200 {
86 case BOW: 201 case BOW:
87 case WAND: 202 case WAND:
88 case ROD: 203 case ROD:
89 case HORN: 204 case HORN:
90 flags = a_readied; 205 flags = a_readied;
111 default: 226 default:
112 flags = a_applied; 227 flags = a_applied;
113 break; 228 break;
114 } 229 }
115 } 230 }
231
116 if (op->type == CONTAINER && ((op->env && op->env->container == op) || 232 if (op->type == CONTAINER && ((op->env && op->env->container == op) || (!op->env && QUERY_FLAG (op, FLAG_APPLIED))))
117 (!op->env && QUERY_FLAG(op,FLAG_APPLIED))))
118 flags |= F_OPEN; 233 flags |= F_OPEN;
119 234
120 if (QUERY_FLAG(op,FLAG_KNOWN_CURSED)) { 235 if (QUERY_FLAG (op, FLAG_KNOWN_CURSED))
236 {
121 if(QUERY_FLAG(op,FLAG_DAMNED)) 237 if (QUERY_FLAG (op, FLAG_DAMNED))
122 flags |= F_DAMNED; 238 flags |= F_DAMNED;
123 else if(QUERY_FLAG(op,FLAG_CURSED)) 239 else if (QUERY_FLAG (op, FLAG_CURSED))
124 flags |= F_CURSED; 240 flags |= F_CURSED;
125 } 241 }
242
126 if (QUERY_FLAG(op,FLAG_KNOWN_MAGICAL) && !QUERY_FLAG(op,FLAG_IDENTIFIED)) 243 if (QUERY_FLAG (op, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (op, FLAG_IDENTIFIED))
127 flags |= F_MAGIC; 244 flags |= F_MAGIC;
128 if (QUERY_FLAG(op,FLAG_UNPAID)) 245 if (QUERY_FLAG (op, FLAG_UNPAID))
129 flags |= F_UNPAID; 246 flags |= F_UNPAID;
130 if (QUERY_FLAG(op,FLAG_INV_LOCKED)) 247 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
131 flags |= F_LOCKED; 248 flags |= F_LOCKED;
132 249
133 return flags; 250 return flags;
134} 251}
135 252
136/* Used in the send_look to put object head into SockList 253/* Used in the send_look to put object head into packet
137 * sl for socket ns. Need socket to know if we need to send 254 * sl for socket ns. Need socket to know if we need to send
138 * animation of face to the client. 255 * animation of face to the client.
139 */ 256 */
140static void add_object_to_socklist(NewSocket *ns, SockList *sl, object *head) 257static void
258add_object_to_socklist (client &ns, packet &sl, object *head)
141{ 259{
142 int flags, len, anim_speed; 260 int flags, len, anim_speed;
143 char item_n[MAX_BUF]; 261 char item_n[MAX_BUF];
144 const char *item_p; 262 const char *item_p;
145 263
146 flags = query_flags (head); 264 flags = query_flags (head);
147 if (QUERY_FLAG(head, FLAG_NO_PICK)) 265 if (QUERY_FLAG (head, FLAG_NO_PICK))
148 flags |= F_NOPICK; 266 flags |= F_NOPICK;
149 267
150 if (!(ns->faces_sent[head->face->number] & NS_FACESENT_FACE)) 268 if (!(ns.faces_sent[head->face->number] & NS_FACESENT_FACE))
151 esrv_send_face(ns, head->face->number,0); 269 esrv_send_face (&ns, head->face->number, 0);
152 270
153 if (QUERY_FLAG(head,FLAG_ANIMATE) && !ns->anims_sent[head->animation_id]) 271 if (QUERY_FLAG (head, FLAG_ANIMATE) && !ns.anims_sent[head->animation_id])
154 esrv_send_animation(ns, head->animation_id); 272 esrv_send_animation (&ns, head->animation_id);
155 273
156 SockList_AddInt(sl, head->count); 274 sl << uint32 (head->count)
157 SockList_AddInt(sl, flags); 275 << uint32 (flags)
158 SockList_AddInt(sl, QUERY_FLAG(head, FLAG_NO_PICK) ? -1 : WEIGHT(head)); 276 << uint32 (QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : WEIGHT (head))
159 SockList_AddInt(sl, head->face->number); 277 << uint32 (head->face->number);
160 278
161 if (!head->custom_name) { 279 if (!head->custom_name)
280 {
162 strncpy(item_n,query_base_name(head, 0),127); 281 strncpy (item_n, query_base_name (head, 0), 127);
163 item_n[127]=0; 282 item_n[127] = 0;
164 len=strlen(item_n); 283 len = strlen (item_n);
165 item_p=query_base_name(head, 1); 284 item_p = query_base_name (head, 1);
166 } else { 285 }
286 else
287 {
167 strncpy(item_n,head->custom_name,127); 288 strncpy (item_n, head->custom_name, 127);
168 item_n[127]=0; 289 item_n[127] = 0;
169 len=strlen(item_n); 290 len = strlen (item_n);
170 item_p=head->custom_name; 291 item_p = head->custom_name;
171 } 292 }
293
172 strncpy(item_n+len+1, item_p, 127); 294 strncpy (item_n + len + 1, item_p, 127);
173 item_n[254]=0; 295 item_n[254] = 0;
174 len += strlen(item_n+1+len) + 1; 296 len += strlen (item_n + 1 + len) + 1;
175 SockList_AddChar(sl, (char ) len);
176 memcpy(sl->buf+sl->len, item_n, len);
177 sl->len += len;
178 297
179 SockList_AddShort(sl,head->animation_id); 298 sl << data8 (item_n, len)
299 << uint16 (head->animation_id);
300
180 anim_speed=0; 301 anim_speed = 0;
181 if (QUERY_FLAG(head,FLAG_ANIMATE)) { 302 if (QUERY_FLAG (head, FLAG_ANIMATE))
303 {
304 if (head->anim_speed)
182 if (head->anim_speed) anim_speed=head->anim_speed; 305 anim_speed = head->anim_speed;
306 else
307 {
308 if (FABS (head->speed) < 0.001)
309 anim_speed = 255;
310 else if (FABS (head->speed) >= 1.0)
311 anim_speed = 1;
183 else { 312 else
184 if (FABS(head->speed)<0.001) anim_speed=255;
185 else if (FABS(head->speed)>=1.0) anim_speed=1;
186 else anim_speed = (int) (1.0/FABS(head->speed)); 313 anim_speed = (int) (1.0 / FABS (head->speed));
187 } 314 }
188 if (anim_speed>255) anim_speed=255;
189 }
190 SockList_AddChar(sl, (char) anim_speed);
191 SockList_AddInt(sl, head->nrof);
192 315
316 if (anim_speed > 255)
317 anim_speed = 255;
318 }
319
320 sl << uint8 (anim_speed)
321 << uint32 (head->nrof);
322
193 if (ns->itemcmd == 2) 323 if (ns.itemcmd == 2)
194 SockList_AddShort(sl, head->client_type); 324 sl << uint16 (head->client_type);
195 325
196 SET_FLAG(head, FLAG_CLIENT_SENT); 326 SET_FLAG (head, FLAG_CLIENT_SENT);
197} 327}
198 328
199 329
200/** 330/**
201 * Send the look window. Don't need to do animations here 331 * Send the look window. Don't need to do animations here
202 * This sends all the faces to the client, not just updates. This is 332 * This sends all the faces to the client, not just updates. This is
203 * because object ordering would otherwise be inconsistent 333 * because object ordering would otherwise be inconsistent.
204 */ 334 */
205 335void
206void esrv_draw_look(object *pl) 336esrv_draw_look (object *pl)
207{ 337{
208 object *tmp, *last; 338 object *tmp, *last;
209 int got_one=0,start_look=0, end_look=0; 339 int got_one = 0, start_look = 0, end_look = 0;
210 SockList sl;
211 char buf[MAX_BUF]; 340 char buf[MAX_BUF];
212 341
213 if (!pl->contr->socket.update_look) { 342 if (!pl->contr->ns->update_look)
343 {
214 LOG(llevDebug,"esrv_draw_look called when update_look was not set\n"); 344 LOG (llevDebug, "esrv_draw_look called when update_look was not set\n");
215 return; 345 return;
216 } else { 346 }
347 else
217 pl->contr->socket.update_look=0; 348 pl->contr->ns->update_look = 0;
218 }
219 349
220 if(QUERY_FLAG(pl, FLAG_REMOVED) || pl->map == NULL || 350 if (QUERY_FLAG (pl, FLAG_REMOVED)
221 pl->map->in_memory != MAP_IN_MEMORY || out_of_map(pl->map,pl->x,pl->y)) 351 || !pl->map
222 return; 352 || pl->map->in_memory != MAP_IN_MEMORY
353 || out_of_map (pl->map, pl->x, pl->y))
354 return;
223 355
224 for (tmp=get_map_ob(pl->map,pl->x,pl->y); tmp && tmp->above;tmp=tmp->above) ; 356 for (tmp = GET_MAP_OB (pl->map, pl->x, pl->y); tmp && tmp->above; tmp = tmp->above)
357 ;
225 358
226 sl.buf= (unsigned char *) malloc(MAXSOCKBUF); 359 pl->contr->ns->send_packet ("delinv 0");
227 360
228 Write_String_To_Socket(&pl->contr->socket, "delinv 0", strlen("delinv 0")); 361 packet sl;
229 sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); 362 sl.printf ("item%d ", pl->contr->ns->itemcmd);
230 sl.len=strlen((char*)sl.buf);
231 363
232 SockList_AddInt(&sl, 0); 364 sl << uint32 (0);
233 365
234 if (!(pl->contr->socket.faces_sent[empty_face->number]&NS_FACESENT_FACE)) 366 if (!(pl->contr->ns->faces_sent[empty_face->number] & NS_FACESENT_FACE))
235 esrv_send_face(&pl->contr->socket, empty_face->number,0); 367 esrv_send_face (pl->contr->ns, empty_face->number, 0);
236 368
237 if (pl->contr->socket.look_position) { 369 if (pl->contr->ns->look_position)
238 SockList_AddInt(&sl, 0x80000000 | (pl->contr->socket.look_position- NUM_LOOK_OBJECTS)); 370 {
239 SockList_AddInt(&sl, 0); 371 char buf[80];
240 SockList_AddInt(&sl, (uint32) -1); 372 snprintf (buf, 80, "Apply this to see %d previous items", FLOORBOX_PAGESIZE);
241 SockList_AddInt(&sl, empty_face->number); 373
242 sprintf(buf,"Click here to see %d previous items", NUM_LOOK_OBJECTS); 374 sl << uint32 (0x80000000 | (pl->contr->ns->look_position - FLOORBOX_PAGESIZE))
243 add_stringlen_to_sockbuf(buf, &sl); 375 << uint32 (0)
244 SockList_AddShort(&sl,0); 376 << sint32 (-1)
245 SockList_AddChar(&sl, 0); 377 << uint32 (empty_face->number)
246 SockList_AddInt(&sl, 0); 378 << data8 (buf)
379 << uint16 (0)
380 << uint8 (0)
381 << uint32 (0);
382
247 if (pl->contr->socket.itemcmd == 2) 383 if (pl->contr->ns->itemcmd == 2)
248 SockList_AddShort(&sl, 0); 384 sl << uint16 (0);
249 } 385 }
250 386
251 for (last=NULL; tmp!=last; tmp=tmp->below) { 387 for (last = NULL; tmp != last; tmp = tmp->below)
388 {
252 object *head; 389 object *head;
253 390
254 if (QUERY_FLAG(tmp, FLAG_IS_FLOOR) && !last) { 391 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR) && !last)
392 {
255 last = tmp->below; /* assumes double floor mode */ 393 last = tmp->below; /* assumes double floor mode */
256 if (last && QUERY_FLAG(last, FLAG_IS_FLOOR)) 394 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR))
257 last = last->below; 395 last = last->below;
258 } 396 }
397
259 if (LOOK_OBJ(tmp)) { 398 if (LOOK_OBJ (tmp))
399 {
260 if (++start_look < pl->contr->socket.look_position) continue; 400 if (++start_look < pl->contr->ns->look_position)
401 continue;
402
261 end_look++; 403 end_look++;
262 if (end_look > NUM_LOOK_OBJECTS) { 404
405 if (end_look > FLOORBOX_PAGESIZE)
406 {
263 /* What we basically do is make a 'fake' object - when the user applies it, 407 /* What we basically do is make a 'fake' object - when the user applies it,
264 * we notice the special tag the object has, and act accordingly. 408 * we notice the special tag the object has, and act accordingly.
265 */ 409 */
266 SockList_AddInt(&sl, 0x80000000 | (pl->contr->socket.look_position+ NUM_LOOK_OBJECTS)); 410 sl << uint32 (0x80000000 | (pl->contr->ns->look_position + FLOORBOX_PAGESIZE))
267 SockList_AddInt(&sl, 0); 411 << uint32 (0)
268 SockList_AddInt(&sl, (uint32) -1); 412 << uint32 ((uint32) - 1)
269 SockList_AddInt(&sl, empty_face->number); 413 << uint32 (empty_face->number)
270 sprintf(buf,"Click here to see next group of items"); 414 << data8 ("Apply this to see next group of items")
271 add_stringlen_to_sockbuf(buf, &sl); 415 << uint16 (0)
272 SockList_AddShort(&sl,0); 416 << uint8 (0)
273 SockList_AddChar(&sl, 0); 417 << uint32 (0);
274 SockList_AddInt(&sl, 0); 418
275 if (pl->contr->socket.itemcmd == 2) 419 if (pl->contr->ns->itemcmd == 2)
276 SockList_AddShort(&sl, 0); 420 sl << uint16 (0);
421
277 break; 422 break;
278 } 423 }
424
425 if (tmp->head)
279 if (tmp->head) head = tmp->head; 426 head = tmp->head;
427 else
280 else head = tmp; 428 head = tmp;
281 429
282 add_object_to_socklist(&pl->contr->socket, &sl, head); 430 add_object_to_socklist (*pl->contr->ns, sl, head);
283 got_one++; 431 got_one++;
284 432
285 if (sl.len >= (MAXSOCKBUF-MAXITEMLEN)) { 433 if (sl.length () >= (MAXSOCKBUF - MAXITEMLEN))
286 Send_With_Handling(&pl->contr->socket, &sl); 434 {
435 pl->contr->ns->send_packet (sl);
436
437 sl.reset ();
287 sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); 438 sl.printf ("item%d ", pl->contr->ns->itemcmd);
288 sl.len=strlen((char*)sl.buf); 439 sl << uint32 (0);
289 SockList_AddInt(&sl, 0);
290 got_one=0; 440 got_one = 0;
291 } 441 }
292 } /* If LOOK_OBJ() */ 442 }
293 } 443 }
444
294 if (got_one) 445 if (got_one)
295 Send_With_Handling(&pl->contr->socket, &sl); 446 pl->contr->ns->send_packet (sl);
296 447
297 free(sl.buf);
298} 448}
299 449
300/** 450/**
301 * Sends whole inventory. 451 * Sends whole inventory.
302 */ 452 */
453void
303void esrv_send_inventory(object *pl, object *op) 454esrv_send_inventory (object *pl, object *op)
304{ 455{
305 object *tmp; 456 object *tmp;
306 int got_one=0; 457 int got_one = 0;
307 SockList sl;
308
309 sl.buf= (unsigned char *) malloc(MAXSOCKBUF);
310 458
311 sprintf((char*)sl.buf,"delinv %d", op->count);
312 sl.len=strlen((char*)sl.buf);
313 Send_With_Handling(&pl->contr->socket, &sl);
314 459
460 pl->contr->ns->send_packet_printf ("delinv %d", op->count);
461
462 packet sl;
315 sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); 463 sl.printf ("item%d ", pl->contr->ns->itemcmd);
316 sl.len=strlen((char*)sl.buf);
317 464
318 SockList_AddInt(&sl, op->count); 465 sl << uint32 (op->count);
319 466
320 for (tmp=op->inv; tmp; tmp=tmp->below) { 467 for (tmp = op->inv; tmp; tmp = tmp->below)
468 {
321 object *head; 469 object *head;
322 470
471 if (tmp->head)
323 if (tmp->head) head = tmp->head; 472 head = tmp->head;
473 else
324 else head = tmp; 474 head = tmp;
325 475
326 if (LOOK_OBJ(head)) { 476 if (LOOK_OBJ (head))
327 add_object_to_socklist(&pl->contr->socket, &sl, head);
328 477 {
478 add_object_to_socklist (*pl->contr->ns, sl, head);
479
329 got_one++; 480 got_one++;
330 481
331 /* IT is possible for players to accumulate a huge amount of 482 /* IT is possible for players to accumulate a huge amount of
332 * items (especially with some of the bags out there) to 483 * items (especially with some of the bags out there) to
333 * overflow the buffer. IF so, send multiple item commands. 484 * overflow the buffer. IF so, send multiple item commands.
334 */ 485 */
335 if (sl.len >= (MAXSOCKBUF-MAXITEMLEN)) { 486 if (sl.length () >= (MAXSOCKBUF - MAXITEMLEN))
336 Send_With_Handling(&pl->contr->socket, &sl); 487 {
488 pl->contr->ns->send_packet (sl);
489
490 sl.reset ();
337 sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); 491 sl.printf ("item%d ", pl->contr->ns->itemcmd);
338 sl.len=strlen((char*)sl.buf); 492 sl << uint32 (op->count);
339 SockList_AddInt(&sl, op->count);
340 got_one=0; 493 got_one = 0;
341 } 494 }
342 } /* If LOOK_OBJ() */ 495 } /* If LOOK_OBJ() */
343 } 496 }
497
344 if (got_one) 498 if (got_one)
345 Send_With_Handling(&pl->contr->socket, &sl); 499 pl->contr->ns->send_packet (sl);
346 free(sl.buf);
347} 500}
348 501
349/** 502/**
350 * Updates object *op for player *pl. 503 * Updates object *op for player *pl.
351 * 504 *
352 * flags is a list of values to update 505 * flags is a list of values to update
353 * to the client (as defined in newclient.h - might as well use the 506 * to the client (as defined in newclient.h - might as well use the
354 * same value both places. 507 * same value both places.
355 */ 508 */
356 509
510void
357void esrv_update_item(int flags, object *pl, object *op) 511esrv_update_item (int flags, object *pl, object *op)
358{ 512{
359 SockList sl;
360
361 /* If we have a request to send the player item, skip a few checks. */ 513 /* If we have a request to send the player item, skip a few checks. */
362 if (op!=pl) { 514 if (op != pl)
515 {
363 if (! LOOK_OBJ(op)) 516 if (!LOOK_OBJ (op))
364 return; 517 return;
365 /* we remove the check for op->env, because in theory, the object 518 /* we remove the check for op->env, because in theory, the object
366 * is hopefully in the same place, so the client should preserve 519 * is hopefully in the same place, so the client should preserve
367 * order. 520 * order.
368 */ 521 */
369 } 522 }
523
370 if (!QUERY_FLAG(op, FLAG_CLIENT_SENT)) { 524 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT))
525 {
371 /* FLAG_CLIENT_SENT is debug only. We are using it to see where 526 /* FLAG_CLIENT_SENT is debug only. We are using it to see where
372 * this is happening - we can set a breakpoint here in the debugger 527 * this is happening - we can set a breakpoint here in the debugger
373 * and track back the call. 528 * and track back the call.
374 */ 529 */
375 LOG(llevDebug,"We have not sent item %s (%d)\n", &op->name, op->count); 530 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count);
376 } 531 }
377 sl.buf= (unsigned char *) malloc(MAXSOCKBUF);
378 532
379 strcpy((char*)sl.buf,"upditem "); 533 packet sl ("upditem");
380 sl.len=strlen((char*)sl.buf);
381 534
382 SockList_AddChar(&sl, (char) flags); 535 sl << uint8 (flags);
383 536
384 if (op->head) op=op->head; 537 if (op->head)
538 op = op->head;
385 539
386 SockList_AddInt(&sl, op->count); 540 sl << uint32 (op->count);
387 541
388 if (flags & UPD_LOCATION) 542 if (flags & UPD_LOCATION)
389 SockList_AddInt(&sl, op->env? op->env->count:0); 543 sl << uint32 (op->env ? op->env->count : 0);
390 544
391 if (flags & UPD_FLAGS) 545 if (flags & UPD_FLAGS)
392 SockList_AddInt(&sl, query_flags(op)); 546 sl << uint32 (query_flags (op));
393 547
394 if (flags & UPD_WEIGHT) { 548 if (flags & UPD_WEIGHT)
549 {
395 sint32 weight = WEIGHT(op); 550 sint32 weight = WEIGHT (op);
396 551
397 SockList_AddInt(&sl, QUERY_FLAG(op, FLAG_NO_PICK) ? -1 : weight); 552 sl << uint32 (QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight);
553
398 if (pl == op) { 554 if (pl == op)
399 op->contr->last_weight = weight; 555 op->contr->last_weight = weight;
400 }
401 } 556 }
402 557
403 if (flags & UPD_FACE) { 558 if (flags & UPD_FACE)
559 {
404 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE)) 560 if (!(pl->contr->ns->faces_sent[op->face->number] & NS_FACESENT_FACE))
405 esrv_send_face(&pl->contr->socket, op->face->number,0); 561 esrv_send_face (pl->contr->ns, op->face->number, 0);
406 SockList_AddInt(&sl, op->face->number); 562
563 sl << uint32 (op->face->number);
407 } 564 }
565
408 if (flags & UPD_NAME) { 566 if (flags & UPD_NAME)
567 {
409 int len; 568 int len;
410 const char *item_p; 569 const char *item_p;
411 char item_n[MAX_BUF]; 570 char item_n[MAX_BUF];
412 571
413 if (!op->custom_name) { 572 if (!op->custom_name)
573 {
414 strncpy(item_n,query_base_name(op, 0),127); 574 strncpy (item_n, query_base_name (op, 0), 127);
415 item_n[127]=0; 575 item_n[127] = 0;
416 len=strlen(item_n); 576 len = strlen (item_n);
417 item_p=query_base_name(op, 1); 577 item_p = query_base_name (op, 1);
578 }
579 else
418 } 580 {
419 else {
420 strncpy(item_n,op->custom_name,127); 581 strncpy (item_n, op->custom_name, 127);
421 item_n[127]=0; 582 item_n[127] = 0;
422 len=strlen(item_n); 583 len = strlen (item_n);
423 item_p=op->custom_name; 584 item_p = op->custom_name;
424 } 585 }
425 586
426 strncpy(item_n+len+1, item_p, 127); 587 strncpy (item_n + len + 1, item_p, 127);
427 item_n[254]=0; 588 item_n[254] = 0;
428 len += strlen(item_n+1+len) + 1; 589 len += strlen (item_n + 1 + len) + 1;
429 SockList_AddChar(&sl, (char)len); 590
430 memcpy(sl.buf+sl.len, item_n, len); 591 sl << data8 (item_n, len);
431 sl.len += len;
432 } 592 }
593
433 if (flags & UPD_ANIM) 594 if (flags & UPD_ANIM)
434 SockList_AddShort(&sl,op->animation_id); 595 sl << uint16 (op->animation_id);
435 596
436 if (flags & UPD_ANIMSPEED) { 597 if (flags & UPD_ANIMSPEED)
598 {
437 int anim_speed=0; 599 int anim_speed = 0;
600
438 if (QUERY_FLAG(op,FLAG_ANIMATE)) { 601 if (QUERY_FLAG (op, FLAG_ANIMATE))
602 {
603 if (op->anim_speed)
439 if (op->anim_speed) anim_speed=op->anim_speed; 604 anim_speed = op->anim_speed;
605 else
606 {
607 if (FABS (op->speed) < 0.001)
608 anim_speed = 255;
609 else if (FABS (op->speed) >= 1.0)
610 anim_speed = 1;
440 else { 611 else
441 if (FABS(op->speed)<0.001) anim_speed=255;
442 else if (FABS(op->speed)>=1.0) anim_speed=1;
443 else anim_speed = (int) (1.0/FABS(op->speed)); 612 anim_speed = (int) (1.0 / FABS (op->speed));
444 } 613 }
445 if (anim_speed>255) anim_speed=255; 614
615 if (anim_speed > 255)
616 anim_speed = 255;
446 } 617 }
447 SockList_AddChar(&sl, (char)anim_speed); 618
619 sl << uint8 (anim_speed);
448 } 620 }
621
449 if (flags & UPD_NROF) 622 if (flags & UPD_NROF)
450 SockList_AddInt(&sl, op->nrof); 623 sl << uint32 (op->nrof);
451 624
452 Send_With_Handling(&pl->contr->socket, &sl); 625 pl->contr->ns->send_packet (sl);
453 free(sl.buf);
454} 626}
455 627
456/** 628/**
457 * Sends item's info to player. 629 * Sends item's info to player.
458 */ 630 */
631void
459void esrv_send_item(object *pl, object*op) 632esrv_send_item (object *pl, object *op)
460{ 633{
461 SockList sl;
462
463 /* If this is not the player object, do some more checks */ 634 /* If this is not the player object, do some more checks */
464 if (op!=pl) { 635 if (op != pl)
636 {
465 /* We only send 'visibile' objects to the client */ 637 /* We only send 'visibile' objects to the client */
466 if (! LOOK_OBJ(op)) 638 if (!LOOK_OBJ (op))
467 return; 639 return;
468 /* if the item is on the ground, mark that the look needs to 640 /* if the item is on the ground, mark that the look needs to
469 * be updated. 641 * be updated.
470 */ 642 */
471 if (!op->env) { 643 if (!op->env)
472 pl->contr->socket.update_look=1; 644 {
645 pl->contr->ns->floorbox_update ();
473 return; 646 return;
474 } 647 }
475 } 648 }
476 649
477 sl.buf= (unsigned char *) malloc(MAXSOCKBUF); 650 packet sl;
478 651
479 sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); 652 sl.printf ("item%d ", pl->contr->ns->itemcmd);
480 sl.len=strlen((char*)sl.buf);
481 653
482 if (op->head) op=op->head; 654 if (op->head)
655 op = op->head;
483 656
484 SockList_AddInt(&sl, op->env? op->env->count:0); 657 sl << uint32 (op->env ? op->env->count : 0);
485 658
486 add_object_to_socklist(&pl->contr->socket, &sl, op); 659 add_object_to_socklist (*pl->contr->ns, sl, op);
487 660
488 Send_With_Handling(&pl->contr->socket, &sl); 661 pl->contr->ns->send_packet (sl);
489 SET_FLAG(op, FLAG_CLIENT_SENT); 662 SET_FLAG (op, FLAG_CLIENT_SENT);
490 free(sl.buf);
491} 663}
492 664
493/** 665/**
494 * Tells the client to delete an item. Uses the item 666 * Tells the client to delete an item. Uses the item
495 * command with a -1 location. 667 * command with a -1 location.
496 */ 668 */
497 669
670void
498void esrv_del_item(player *pl, int tag) 671esrv_del_item (player *pl, int tag)
499{ 672{
500 SockList sl; 673 packet sl ("delitem");
501 674
502 sl.buf= (unsigned char *) malloc(MAXSOCKBUF); 675 sl << uint32 (tag);
503 676
504 strcpy((char*)sl.buf,"delitem "); 677 pl->ns->send_packet (sl);
505 sl.len=strlen((char*)sl.buf);
506 SockList_AddInt(&sl, tag);
507
508 Send_With_Handling(&pl->socket, &sl);
509 free(sl.buf);
510} 678}
511 679
512 680
513/******************************************************************************* 681/*******************************************************************************
514 * 682 *
519/** 687/**
520 * Takes a player and object count (tag) and returns the actual object 688 * Takes a player and object count (tag) and returns the actual object
521 * pointer, or null if it can't be found. 689 * pointer, or null if it can't be found.
522 */ 690 */
523 691
692object *
524object *esrv_get_ob_from_count(object *pl, tag_t count) 693esrv_get_ob_from_count (object *pl, tag_t count)
525{ 694{
526 object *op, *tmp; 695 object *op, *tmp;
527 696
528 if (pl->count == count) 697 if (pl->count == count)
529 return pl; 698 return pl;
530 699
531 for(op = pl->inv; op; op = op->below) 700 for (op = pl->inv; op; op = op->below)
532 if (op->count == count) 701 if (op->count == count)
533 return op; 702 return op;
534 else if (op->type == CONTAINER && pl->container == op) 703 else if (op->type == CONTAINER && pl->container == op)
535 for(tmp = op->inv; tmp; tmp = tmp->below) 704 for (tmp = op->inv; tmp; tmp = tmp->below)
536 if (tmp->count == count) 705 if (tmp->count == count)
537 return tmp;
538
539 for(op = get_map_ob (pl->map, pl->x, pl->y); op; op = op->above)
540 if (op->head != NULL && op->head->count == count)
541 return op; 706 return tmp;
707
708 for (op = GET_MAP_OB (pl->map, pl->x, pl->y); op; op = op->above)
709 if (op->head && op->head->count == count)
710 return op;
542 else if (op->count == count) 711 else if (op->count == count)
543 return op; 712 return op;
544 else if (op->type == CONTAINER && pl->container == op) 713 else if (op->type == CONTAINER && pl->container == op)
545 for(tmp = op->inv; tmp; tmp = tmp->below) 714 for (tmp = op->inv; tmp; tmp = tmp->below)
546 if (tmp->count == count) 715 if (tmp->count == count)
547 return tmp; 716 return tmp;
548 717
549 return NULL; 718 return 0;
550} 719}
551 720
552 721
553/** Client wants to examine some object. So lets do so. */ 722/** Client wants to examine some object. So lets do so. */
723void
554void ExamineCmd(char *buf, int len,player *pl) 724ExamineCmd (char *buf, int len, player *pl)
555{ 725{
556 long tag = atoi(buf); 726 tag_t tag = atoi (buf);
727
728 /* If the high bit is set, player examined a pseudo object. */
729 if (tag & 0x80000000)
730 return;
731
557 object *op = esrv_get_ob_from_count(pl->ob, tag); 732 object *op = esrv_get_ob_from_count (pl->ob, tag);
558 733
559 if (!op) { 734 if (!op)
735 {
560 LOG(llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag); 736 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag);
561 return; 737 return;
562 } 738 }
739
563 examine (pl->ob, op); 740 examine (pl->ob, op);
564} 741}
565 742
566/** Client wants to apply some object. Lets do so. */ 743/** Client wants to apply some object. Lets do so. */
744void
567void ApplyCmd(char *buf, int len,player *pl) 745ApplyCmd (char *buf, int len, player *pl)
568{ 746{
569 uint32 tag = atoi(buf); 747 tag_t tag = atoi (buf);
570 object *op = esrv_get_ob_from_count(pl->ob, tag);
571 748
572 /* sort of a hack, but if the player saves and the player then manually 749 /* sort of a hack, but if the player saves and the player then manually
573 * applies a savebed (or otherwise tries to do stuff), we run into trouble. 750 * applies a savebed (or otherwise tries to do stuff), we run into trouble.
574 */ 751 */
575 if (QUERY_FLAG(pl->ob, FLAG_REMOVED)) return; 752 if (QUERY_FLAG (pl->ob, FLAG_REMOVED))
753 return;
576 754
577 /* If the high bit is set, player applied a pseudo object. */ 755 /* If the high bit is set, player applied a pseudo object. */
578 if (tag & 0x80000000) { 756 if (tag & 0x80000000)
757 {
579 pl->socket.look_position = tag & 0x7fffffff; 758 pl->ns->look_position = tag & 0x7fffffff;
580 pl->socket.update_look = 1; 759 pl->ns->floorbox_update ();
581 return; 760 return;
582 } 761 }
583 762
763 object *op = esrv_get_ob_from_count (pl->ob, tag);
764
584 if (!op) { 765 if (!op)
766 {
585 LOG(llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag); 767 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag);
586 return; 768 return;
587 } 769 }
770
588 player_apply (pl->ob, op, 0, 0); 771 player_apply (pl->ob, op, 0, 0);
589} 772}
590 773
591/** Client wants to apply some object. Lets do so. */ 774/** Client wants to lock some object. Lets do so. */
775void
592void LockItem(uint8 *data, int len,player *pl) 776LockItem (char *data, int len, player *pl)
593{ 777{
594 int flag, tag;
595 object *op;
596
597 flag = data[0]; 778 int flag = data[0];
598 tag = GetInt_String(data+1); 779 tag_t tag = net_uint32 ((uint8 *)data + 1);
599 op = esrv_get_ob_from_count(pl->ob, tag); 780 object *op = esrv_get_ob_from_count (pl->ob, tag);
600 781
601 if (!op) { 782 if (!op)
783 {
602 new_draw_info(NDI_UNIQUE, 0, pl->ob,"Could not find object to lock/unlock"); 784 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock");
603 return; 785 return;
604 } 786 }
787
605 if (!flag) 788 if (!flag)
606 CLEAR_FLAG(op,FLAG_INV_LOCKED); 789 CLEAR_FLAG (op, FLAG_INV_LOCKED);
607 else 790 else
608 SET_FLAG(op,FLAG_INV_LOCKED); 791 SET_FLAG (op, FLAG_INV_LOCKED);
792
609 esrv_update_item(UPD_FLAGS, pl->ob, op); 793 esrv_update_item (UPD_FLAGS, pl->ob, op);
610} 794}
611 795
612/** Client wants to apply some object. Lets do so. */ 796/** Client wants to mark some object. Lets do so. */
797void
613void MarkItem(uint8 *data, int len,player *pl) 798MarkItem (char *data, int len, player *pl)
614{ 799{
615 int tag; 800 tag_t tag = net_uint32 ((uint8 *)data);
616 object *op;
617
618 tag = GetInt_String(data);
619 op = esrv_get_ob_from_count(pl->ob, tag); 801 object *op = esrv_get_ob_from_count (pl->ob, tag);
802
620 if (!op) { 803 if (!op)
804 {
621 new_draw_info(NDI_UNIQUE, 0, pl->ob,"Could not find object to mark"); 805 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark");
622 return; 806 return;
623 } 807 }
808
624 pl->mark = op; 809 pl->mark = op;
625 pl->mark_count = op->count;
626 new_draw_info_format(NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name(op)); 810 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op));
627} 811}
628
629 812
630/** 813/**
631 * look_at prints items on the specified square. 814 * look_at prints items on the specified square.
632 * 815 *
633 * [ removed EARTHWALL check and added check for containers inventory. 816 * [ removed EARTHWALL check and added check for containers inventory.
634 * Tero.Haatanen@lut.fi ] 817 * Tero.Haatanen@lut.fi ]
635 */ 818 */
819void
636void look_at(object *op,int dx,int dy) { 820look_at (object *op, int dx, int dy)
821{
637 object *tmp; 822 object *tmp;
638 int flag=0; 823 int flag = 0;
639 sint16 x,y; 824 sint16 x, y;
640 mapstruct *m; 825 maptile *m;
641 826
642 x = op->x + dx; 827 x = op->x + dx;
643 y = op->y + dy; 828 y = op->y + dy;
644 829
645 if (out_of_map(op->map, x, y)) return; 830 if (out_of_map (op->map, x, y))
831 return;
646 832
647 m = get_map_from_coord(op->map, &x, &y); 833 m = get_map_from_coord (op->map, &x, &y);
648 if (!m) return; 834 if (!m)
835 return;
649 836
650 for(tmp=get_map_ob(m, x ,y);tmp!=NULL&&tmp->above!=NULL; 837 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above);
651 tmp=tmp->above);
652 838
653 for ( ; tmp != NULL; tmp=tmp->below ) { 839 for (; tmp != NULL; tmp = tmp->below)
840 {
654 if (tmp->invisible && !QUERY_FLAG(op, FLAG_WIZ)) continue; 841 if (tmp->invisible && !QUERY_FLAG (op, FLAG_WIZ))
842 continue;
655 843
656 if(!flag) { 844 if (!flag)
845 {
657 if(dx||dy) 846 if (dx || dy)
658 new_draw_info(NDI_UNIQUE, 0,op,"There you see:"); 847 new_draw_info (NDI_UNIQUE, 0, op, "There you see:");
659 else { 848 else
849 {
660 clear_win_info(op); 850 clear_win_info (op);
661 new_draw_info(NDI_UNIQUE, 0,op,"You see:"); 851 new_draw_info (NDI_UNIQUE, 0, op, "You see:");
662 } 852 }
663 flag=1; 853 flag = 1;
664 } 854 }
665 855
666 if (QUERY_FLAG(op, FLAG_WIZ)) 856 if (QUERY_FLAG (op, FLAG_WIZ))
667 new_draw_info_format(NDI_UNIQUE,0, op, "- %s (%d).",query_name(tmp),tmp->count); 857 new_draw_info_format (NDI_UNIQUE, 0, op, "- %s (%d).", query_name (tmp), tmp->count);
668 else 858 else
669 new_draw_info_format(NDI_UNIQUE,0, op, "- %s.",query_name(tmp)); 859 new_draw_info_format (NDI_UNIQUE, 0, op, "- %s.", query_name (tmp));
670 860
671 if (((tmp->inv!=NULL || (tmp->head && tmp->head->inv)) && 861 if (((tmp->inv != NULL || (tmp->head && tmp->head->inv)) &&
672 (tmp->type != CONTAINER && tmp->type!=FLESH)) || QUERY_FLAG(op, FLAG_WIZ)) 862 (tmp->type != CONTAINER && tmp->type != FLESH)) || QUERY_FLAG (op, FLAG_WIZ))
673 inventory(op,tmp->head==NULL?tmp:tmp->head); 863 inventory (op, tmp->head == NULL ? tmp : tmp->head);
674 864
675 if(QUERY_FLAG(tmp, FLAG_IS_FLOOR)&&!QUERY_FLAG(op, FLAG_WIZ)) /* don't continue under the floor */ 865 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR) && !QUERY_FLAG (op, FLAG_WIZ)) /* don't continue under the floor */
676 break; 866 break;
677 } 867 }
678 868
679 if(!flag) { 869 if (!flag)
870 {
680 if(dx||dy) 871 if (dx || dy)
681 new_draw_info(NDI_UNIQUE, 0,op,"You see nothing there."); 872 new_draw_info (NDI_UNIQUE, 0, op, "You see nothing there.");
682 else 873 else
683 new_draw_info(NDI_UNIQUE, 0,op,"You see nothing."); 874 new_draw_info (NDI_UNIQUE, 0, op, "You see nothing.");
684 } 875 }
685} 876}
686 877
687 878
688 879
689/** Client wants to look at some object. Lets do so. */ 880/** Client wants to look at some object. Lets do so. */
881void
690void LookAt(char *buf, int len,player *pl) 882LookAt (char *buf, int len, player *pl)
691{ 883{
692 int dx, dy; 884 int dx, dy;
693 char *cp; 885 char *cp;
694 886
695 dx=atoi(buf); 887 dx = atoi (buf);
696 if (!(cp=strchr(buf,' '))) { 888 if (!(cp = strchr (buf, ' ')))
889 {
890 return;
891 }
892 dy = atoi (cp);
893
894 if (FABS (dx) > pl->ns->mapx / 2 || FABS (dy) > pl->ns->mapy / 2)
895 return;
896
897 if (pl->blocked_los[dx + pl->ns->mapx / 2][dy + pl->ns->mapy / 2])
898 return;
899
900 look_at (pl->ob, dx, dy);
901}
902
903/** Move an object to a new location */
904void
905esrv_move_object (object *pl, tag_t to, tag_t tag, long nrof)
906{
907 object *op, *env;
908
909 op = esrv_get_ob_from_count (pl, tag);
910 if (!op)
911 {
912 LOG (llevDebug, "Player '%s' tried to move an unknown object (%ld)\n", &pl->name, tag);
913 return;
914 }
915
916 if (!to)
917 { /* drop it to the ground */
918 if (op->map && !op->env)
697 return; 919 return;
698 }
699 dy=atoi(cp);
700 920
701 if (FABS(dx) > pl->socket.mapx / 2 || FABS(dy) > pl->socket.mapy / 2) 921 /* If it is an active container, then we should drop all objects
922 * in the container and not the container itself.
923 */
924 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED))
925 {
926 object *current, *next;
927
928 for (current = op->inv; current != NULL; current = next)
929 {
930 next = current->below;
931 drop_object (pl, current, 0);
932 }
933
934 esrv_update_item (UPD_WEIGHT, pl, op);
935 }
936 else
937 drop_object (pl, op, nrof);
938
702 return; 939 return;
703 940 }
704 if(pl->blocked_los[dx + pl->socket.mapx / 2][dy + pl->socket.mapy / 2]) 941 else if (to == pl->count)
705 return; 942 { /* pick it up to the inventory */
706 943 /* return if player has already picked it up */
707 look_at(pl->ob, dx, dy); 944 if (op->env == pl)
708}
709
710/** Move an object to a new location */
711void esrv_move_object (object *pl, tag_t to, tag_t tag, long nrof)
712{
713 object *op, *env;
714
715 op = esrv_get_ob_from_count(pl, tag);
716 if (!op) {
717 LOG(llevDebug, "Player '%s' tried to move an unknown object (%ld)\n", &pl->name, tag);
718 return; 945 return;
719 }
720 946
721 if (!to) { /* drop it to the ground */
722/* LOG(llevDebug, "Drop it on the ground.\n");*/
723
724 if (op->map && !op->env) {
725/* LOG(llevDebug,"Dropping object to ground that is already on ground\n");*/
726 return;
727 }
728 /* If it is an active container, then we should drop all objects
729 * in the container and not the container itself.
730 */
731 if (op->inv && QUERY_FLAG(op, FLAG_APPLIED)) {
732 object *current, *next;
733 for (current=op->inv; current!=NULL; current=next) {
734 next=current->below;
735 drop_object(pl, current, 0);
736 }
737 esrv_update_item(UPD_WEIGHT, pl, op);
738 }
739 else {
740 drop_object (pl, op, nrof);
741 }
742 return;
743 } else if (to == pl->count) { /* pick it up to the inventory */
744 /* return if player has already picked it up */
745 if (op->env == pl) return;
746
747 pl->contr->count = nrof; 947 pl->contr->count = nrof;
748 pick_up(pl, op); 948 pick_up (pl, op);
749 return ; 949 return;
750 } 950 }
951
751 env = esrv_get_ob_from_count(pl, to); 952 env = esrv_get_ob_from_count (pl, to);
752 if (!env) { 953 if (!env)
753 LOG(llevDebug, 954 {
754 "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to); 955 LOG (llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to);
755 return; 956 return;
756 } 957 }
958
757 /* put_object_in_sack presumes that necessary sanity checking 959 /* put_object_in_sack presumes that necessary sanity checking
758 * has already been done (eg, it can be picked up and fits in 960 * has already been done (eg, it can be picked up and fits in
759 * in a sack, so check for those things. We should also check 961 * in a sack, so check for those things. We should also check
760 * an make sure env is in fact a container for that matter. 962 * an make sure env is in fact a container for that matter.
761 */ 963 */
762 if (env->type == CONTAINER
763 && can_pick(pl, op) && sack_can_hold(pl, env, op, nrof)) { 964 if (env->type == CONTAINER && can_pick (pl, op) && sack_can_hold (pl, env, op, nrof))
764 put_object_in_sack (pl, env, op, nrof); 965 put_object_in_sack (pl, env, op, nrof);
765 }
766} 966}
767 967
768

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines