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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines