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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines