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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines