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.26 by root, Tue Dec 19 05:41:22 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 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); 233 snprintf (buf, 80, "Apply this to see %d previous items", FLOORBOX_PAGESIZE);
244 SockList_AddInt(&sl, empty_face->number); 234
245 sprintf(buf,"Click here to see %d previous items", NUM_LOOK_OBJECTS); 235 sl << uint32 (0x80000000 | (pl->contr->socket->look_position - FLOORBOX_PAGESIZE))
246 add_stringlen_to_sockbuf(buf, &sl); 236 << uint32 (0)
247 SockList_AddShort(&sl,0); 237 << sint32 (-1)
248 SockList_AddChar(&sl, 0); 238 << uint32 (empty_face->number)
249 SockList_AddInt(&sl, 0); 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++;
270 if (end_look > NUM_LOOK_OBJECTS) { 265
266 if (end_look > FLOORBOX_PAGESIZE)
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 + FLOORBOX_PAGESIZE))
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 }
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);
355} 363}
356 364
357/** 365/**
358 * Updates object *op for player *pl. 366 * Updates object *op for player *pl.
359 * 367 *
360 * flags is a list of values to update 368 * flags is a list of values to update
361 * to the client (as defined in newclient.h - might as well use the 369 * to the client (as defined in newclient.h - might as well use the
362 * same value both places. 370 * same value both places.
363 */ 371 */
364 372
373void
365void esrv_update_item(int flags, object *pl, object *op) 374esrv_update_item (int flags, object *pl, object *op)
366{ 375{
367 SockList sl;
368
369 /* If we have a request to send the player item, skip a few checks. */ 376 /* If we have a request to send the player item, skip a few checks. */
370 if (op!=pl) { 377 if (op != pl)
378 {
371 if (! LOOK_OBJ(op)) 379 if (!LOOK_OBJ (op))
372 return; 380 return;
373 /* we remove the check for op->env, because in theory, the object 381 /* we remove the check for op->env, because in theory, the object
374 * is hopefully in the same place, so the client should preserve 382 * is hopefully in the same place, so the client should preserve
375 * order. 383 * order.
376 */ 384 */
377 } 385 }
386
378 if (!QUERY_FLAG(op, FLAG_CLIENT_SENT)) { 387 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT))
388 {
379 /* FLAG_CLIENT_SENT is debug only. We are using it to see where 389 /* 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 390 * this is happening - we can set a breakpoint here in the debugger
381 * and track back the call. 391 * and track back the call.
382 */ 392 */
383 LOG(llevDebug,"We have not sent item %s (%d)\n", op->name, op->count); 393 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count);
384 } 394 }
385 sl.buf= (unsigned char *) malloc(MAXSOCKBUF);
386 395
387 strcpy((char*)sl.buf,"upditem "); 396 packet sl;
388 sl.len=strlen((char*)sl.buf);
389 397
390 SockList_AddChar(&sl, (char) flags); 398 sl << "upditem "
399 << uint8 (flags);
391 400
392 if (op->head) op=op->head; 401 if (op->head)
402 op = op->head;
393 403
394 SockList_AddInt(&sl, op->count); 404 sl << uint32 (op->count);
395 405
396 if (flags & UPD_LOCATION) 406 if (flags & UPD_LOCATION)
397 SockList_AddInt(&sl, op->env? op->env->count:0); 407 sl << uint32 (op->env ? op->env->count : 0);
398 408
399 if (flags & UPD_FLAGS) 409 if (flags & UPD_FLAGS)
400 SockList_AddInt(&sl, query_flags(op)); 410 sl << uint32 (query_flags (op));
401 411
402 if (flags & UPD_WEIGHT) { 412 if (flags & UPD_WEIGHT)
413 {
403 sint32 weight = WEIGHT(op); 414 sint32 weight = WEIGHT (op);
404 415
405 /* TRANSPORTS are odd - they sort of look like containers, yet can't be 416 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 417
407 * weight sometimes and not other (the draw_look won't send it 418 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; 419 op->contr->last_weight = weight;
413 }
414 } 420 }
415 421
416 if (flags & UPD_FACE) { 422 if (flags & UPD_FACE)
423 {
417 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE)) 424 if (!(pl->contr->socket->faces_sent[op->face->number] & NS_FACESENT_FACE))
418 esrv_send_face(&pl->contr->socket, op->face->number,0); 425 esrv_send_face (pl->contr->socket, op->face->number, 0);
419 SockList_AddInt(&sl, op->face->number); 426
427 sl << uint32 (op->face->number);
420 } 428 }
429
421 if (flags & UPD_NAME) { 430 if (flags & UPD_NAME)
422 int len; 431 {
432 int len;
423 const char *item_p; 433 const char *item_p;
424 char item_n[MAX_BUF]; 434 char item_n[MAX_BUF];
425 435
426 if (!op->custom_name) { 436 if (!op->custom_name)
437 {
427 strncpy(item_n,query_base_name(op, 0),127); 438 strncpy (item_n, query_base_name (op, 0), 127);
428 item_n[127]=0; 439 item_n[127] = 0;
429 len=strlen(item_n); 440 len = strlen (item_n);
430 item_p=query_base_name(op, 1); 441 item_p = query_base_name (op, 1);
431 } 442 }
432 else { 443 else
444 {
433 strncpy(item_n,op->custom_name,127); 445 strncpy (item_n, op->custom_name, 127);
434 item_n[127]=0; 446 item_n[127] = 0;
435 len=strlen(item_n); 447 len = strlen (item_n);
436 item_p=op->custom_name; 448 item_p = op->custom_name;
437 } 449 }
438 450
439 strncpy(item_n+len+1, item_p, 127); 451 strncpy (item_n + len + 1, item_p, 127);
440 item_n[254]=0; 452 item_n[254] = 0;
441 len += strlen(item_n+1+len) + 1; 453 len += strlen (item_n + 1 + len) + 1;
442 SockList_AddChar(&sl, (char)len); 454
443 memcpy(sl.buf+sl.len, item_n, len); 455 sl << data8 (item_n, len);
444 sl.len += len;
445 } 456 }
457
446 if (flags & UPD_ANIM) 458 if (flags & UPD_ANIM)
447 SockList_AddShort(&sl,op->animation_id); 459 sl << uint16 (op->animation_id);
448 460
449 if (flags & UPD_ANIMSPEED) { 461 if (flags & UPD_ANIMSPEED)
462 {
450 int anim_speed=0; 463 int anim_speed = 0;
464
451 if (QUERY_FLAG(op,FLAG_ANIMATE)) { 465 if (QUERY_FLAG (op, FLAG_ANIMATE))
452 if (op->anim_speed) anim_speed=op->anim_speed; 466 {
453 else { 467 if (op->anim_speed)
454 if (FABS(op->speed)<0.001) anim_speed=255; 468 anim_speed = op->anim_speed;
455 else if (FABS(op->speed)>=1.0) anim_speed=1; 469 else
470 {
471 if (FABS (op->speed) < 0.001)
472 anim_speed = 255;
473 else if (FABS (op->speed) >= 1.0)
474 anim_speed = 1;
475 else
456 else anim_speed = (int) (1.0/FABS(op->speed)); 476 anim_speed = (int) (1.0 / FABS (op->speed));
477 }
478
479 if (anim_speed > 255)
480 anim_speed = 255;
481 }
482
483 sl << uint8 (anim_speed);
457 } 484 }
458 if (anim_speed>255) anim_speed=255; 485
459 }
460 SockList_AddChar(&sl, (char)anim_speed);
461 }
462 if (flags & UPD_NROF) 486 if (flags & UPD_NROF)
463 SockList_AddInt(&sl, op->nrof); 487 sl << uint32 (op->nrof);
464 488
465 Send_With_Handling(&pl->contr->socket, &sl); 489 pl->contr->socket->send_packet (sl);
466 free(sl.buf);
467} 490}
468 491
469/** 492/**
470 * Sends item's info to player. 493 * Sends item's info to player.
471 */ 494 */
495void
472void esrv_send_item(object *pl, object*op) 496esrv_send_item (object *pl, object *op)
473{ 497{
474 SockList sl;
475
476 /* If this is not the player object, do some more checks */ 498 /* If this is not the player object, do some more checks */
477 if (op!=pl) { 499 if (op != pl)
500 {
478 /* We only send 'visibile' objects to the client */ 501 /* We only send 'visibile' objects to the client */
479 if (! LOOK_OBJ(op)) 502 if (!LOOK_OBJ (op))
480 return; 503 return;
481 /* if the item is on the ground, mark that the look needs to 504 /* if the item is on the ground, mark that the look needs to
482 * be updated. 505 * be updated.
483 */ 506 */
484 if (!op->env) { 507 if (!op->env)
485 pl->contr->socket.update_look=1; 508 {
509 pl->contr->socket->floorbox_update ();
486 return; 510 return;
487 } 511 }
488 } 512 }
489 513
490 sl.buf= (unsigned char *) malloc(MAXSOCKBUF); 514 packet sl;
491 515
492 sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); 516 sl.printf ("item%d ", pl->contr->socket->itemcmd);
493 sl.len=strlen((char*)sl.buf);
494 517
495 if (op->head) op=op->head; 518 if (op->head)
519 op = op->head;
496 520
497 SockList_AddInt(&sl, op->env? op->env->count:0); 521 sl << uint32 (op->env ? op->env->count : 0);
498 522
499 add_object_to_socklist(&pl->contr->socket, &sl, op); 523 add_object_to_socklist (*pl->contr->socket, sl, op);
500 524
501 Send_With_Handling(&pl->contr->socket, &sl); 525 pl->contr->socket->send_packet (sl);
502 SET_FLAG(op, FLAG_CLIENT_SENT); 526 SET_FLAG (op, FLAG_CLIENT_SENT);
503 free(sl.buf);
504} 527}
505 528
506/** 529/**
507 * Tells the client to delete an item. Uses the item 530 * Tells the client to delete an item. Uses the item
508 * command with a -1 location. 531 * command with a -1 location.
509 */ 532 */
510 533
534void
511void esrv_del_item(player *pl, int tag) 535esrv_del_item (player *pl, int tag)
512{ 536{
513 SockList sl; 537 packet sl;
514 538
515 sl.buf= (unsigned char *) malloc(MAXSOCKBUF); 539 sl << "delitem "
540 << uint32 (tag);
516 541
517 strcpy((char*)sl.buf,"delitem "); 542 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} 543}
524 544
525 545
526/******************************************************************************* 546/*******************************************************************************
527 * 547 *
532/** 552/**
533 * Takes a player and object count (tag) and returns the actual object 553 * Takes a player and object count (tag) and returns the actual object
534 * pointer, or null if it can't be found. 554 * pointer, or null if it can't be found.
535 */ 555 */
536 556
557object *
537object *esrv_get_ob_from_count(object *pl, tag_t count) 558esrv_get_ob_from_count (object *pl, tag_t count)
538{ 559{
539 object *op, *tmp; 560 object *op, *tmp;
540 561
541 if (pl->count == count) 562 if (pl->count == count)
542 return pl; 563 return pl;
543 564
544 for(op = pl->inv; op; op = op->below) 565 for (op = pl->inv; op; op = op->below)
545 if (op->count == count) 566 if (op->count == count)
546 return op; 567 return op;
547 else if (op->type == CONTAINER && pl->container == op) 568 else if (op->type == CONTAINER && pl->container == op)
548 for(tmp = op->inv; tmp; tmp = tmp->below) 569 for (tmp = op->inv; tmp; tmp = tmp->below)
549 if (tmp->count == count) 570 if (tmp->count == count)
550 return tmp; 571 return tmp;
551 572
552 for(op = get_map_ob (pl->map, pl->x, pl->y); op; op = op->above) 573 for (op = get_map_ob (pl->map, pl->x, pl->y); op; op = op->above)
553 if (op->head != NULL && op->head->count == count) 574 if (op->head && op->head->count == count)
554 return op; 575 return op;
555 else if (op->count == count) 576 else if (op->count == count)
556 return op; 577 return op;
557 else if (op->type == CONTAINER && pl->container == op) 578 else if (op->type == CONTAINER && pl->container == op)
558 for(tmp = op->inv; tmp; tmp = tmp->below) 579 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) 580 if (tmp->count == count)
565 return tmp; 581 return tmp;
566 } 582
567 return NULL; 583 return 0;
568} 584}
569 585
570 586
571/** Client wants to examine some object. So lets do so. */ 587/** Client wants to examine some object. So lets do so. */
588void
572void ExamineCmd(char *buf, int len,player *pl) 589ExamineCmd (char *buf, int len, player *pl)
573{ 590{
574 long tag = atoi(buf); 591 tag_t tag = atoi (buf);
592
593 /* If the high bit is set, player examined a pseudo object. */
594 if (tag & 0x80000000)
595 return;
596
575 object *op = esrv_get_ob_from_count(pl->ob, tag); 597 object *op = esrv_get_ob_from_count (pl->ob, tag);
576 598
577 if (!op) { 599 if (!op)
600 {
578 LOG(llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", 601 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag);
579 pl->ob->name, tag); 602 return;
580 return;
581 } 603 }
604
582 examine (pl->ob, op); 605 examine (pl->ob, op);
583} 606}
584 607
585/** Client wants to apply some object. Lets do so. */ 608/** Client wants to apply some object. Lets do so. */
609void
586void ApplyCmd(char *buf, int len,player *pl) 610ApplyCmd (char *buf, int len, player *pl)
587{ 611{
588 uint32 tag = atoi(buf); 612 tag_t tag = atoi (buf);
589 object *op = esrv_get_ob_from_count(pl->ob, tag);
590 613
591 /* sort of a hack, but if the player saves and the player then manually 614 /* 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. 615 * applies a savebed (or otherwise tries to do stuff), we run into trouble.
593 */ 616 */
594 if (QUERY_FLAG(pl->ob, FLAG_REMOVED)) return; 617 if (QUERY_FLAG (pl->ob, FLAG_REMOVED))
618 return;
595 619
596 /* If the high bit is set, player applied a pseudo object. */ 620 /* If the high bit is set, player applied a pseudo object. */
597 if (tag & 0x80000000) { 621 if (tag & 0x80000000)
622 {
598 pl->socket.look_position = tag & 0x7fffffff; 623 pl->socket->look_position = tag & 0x7fffffff;
599 pl->socket.update_look = 1; 624 pl->socket->floorbox_update ();
600 return; 625 return;
601 } 626 }
602 627
628 object *op = esrv_get_ob_from_count (pl->ob, tag);
629
603 if (!op) { 630 if (!op)
631 {
604 LOG(llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", 632 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag);
605 pl->ob->name, tag); 633 return;
606 return;
607 } 634 }
635
608 player_apply (pl->ob, op, 0, 0); 636 player_apply (pl->ob, op, 0, 0);
609} 637}
610 638
611/** Client wants to apply some object. Lets do so. */ 639/** Client wants to lock some object. Lets do so. */
640void
612void LockItem(uint8 *data, int len,player *pl) 641LockItem (char *data, int len, player *pl)
613{ 642{
614 int flag, tag;
615 object *op;
616
617 flag = data[0]; 643 int flag = data[0];
618 tag = GetInt_String(data+1); 644 tag_t tag = net_uint32 ((uint8 *)data + 1);
619 op = esrv_get_ob_from_count(pl->ob, tag); 645 object *op = esrv_get_ob_from_count (pl->ob, tag);
620 646
621 if (!op) { 647 if (!op)
648 {
622 new_draw_info(NDI_UNIQUE, 0, pl->ob,"Could not find object to lock/unlock"); 649 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock");
623 return; 650 return;
624 } 651 }
652
625 if (!flag) 653 if (!flag)
626 CLEAR_FLAG(op,FLAG_INV_LOCKED); 654 CLEAR_FLAG (op, FLAG_INV_LOCKED);
627 else 655 else
628 SET_FLAG(op,FLAG_INV_LOCKED); 656 SET_FLAG (op, FLAG_INV_LOCKED);
657
629 esrv_update_item(UPD_FLAGS, pl->ob, op); 658 esrv_update_item (UPD_FLAGS, pl->ob, op);
630} 659}
631 660
632/** Client wants to apply some object. Lets do so. */ 661/** Client wants to mark some object. Lets do so. */
662void
633void MarkItem(uint8 *data, int len,player *pl) 663MarkItem (char *data, int len, player *pl)
634{ 664{
635 int tag; 665 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); 666 object *op = esrv_get_ob_from_count (pl->ob, tag);
667
640 if (!op) { 668 if (!op)
669 {
641 new_draw_info(NDI_UNIQUE, 0, pl->ob,"Could not find object to mark"); 670 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark");
642 return; 671 return;
643 } 672 }
673
644 pl->mark = op; 674 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)); 675 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op));
647} 676}
648
649 677
650/** 678/**
651 * look_at prints items on the specified square. 679 * look_at prints items on the specified square.
652 * 680 *
653 * [ removed EARTHWALL check and added check for containers inventory. 681 * [ removed EARTHWALL check and added check for containers inventory.
654 * Tero.Haatanen@lut.fi ] 682 * Tero.Haatanen@lut.fi ]
655 */ 683 */
684void
656void look_at(object *op,int dx,int dy) { 685look_at (object *op, int dx, int dy)
686{
657 object *tmp; 687 object *tmp;
658 int flag=0; 688 int flag = 0;
659 sint16 x,y; 689 sint16 x, y;
660 mapstruct *m; 690 maptile *m;
661 691
662 x = op->x + dx; 692 x = op->x + dx;
663 y = op->y + dy; 693 y = op->y + dy;
664 694
665 if (out_of_map(op->map, x, y)) return; 695 if (out_of_map (op->map, x, y))
696 return;
666 697
667 m = get_map_from_coord(op->map, &x, &y); 698 m = get_map_from_coord (op->map, &x, &y);
668 if (!m) return; 699 if (!m)
700 return;
669 701
670 for(tmp=get_map_ob(m, x ,y);tmp!=NULL&&tmp->above!=NULL; 702 for (tmp = get_map_ob (m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above);
671 tmp=tmp->above);
672 703
673 for ( ; tmp != NULL; tmp=tmp->below ) { 704 for (; tmp != NULL; tmp = tmp->below)
705 {
674 if (tmp->invisible && !QUERY_FLAG(op, FLAG_WIZ)) continue; 706 if (tmp->invisible && !QUERY_FLAG (op, FLAG_WIZ))
707 continue;
675 708
676 if(!flag) { 709 if (!flag)
677 if(dx||dy) 710 {
711 if (dx || dy)
678 new_draw_info(NDI_UNIQUE, 0,op,"There you see:"); 712 new_draw_info (NDI_UNIQUE, 0, op, "There you see:");
679 else { 713 else
680 clear_win_info(op); 714 {
715 clear_win_info (op);
681 new_draw_info(NDI_UNIQUE, 0,op,"You see:"); 716 new_draw_info (NDI_UNIQUE, 0, op, "You see:");
682 } 717 }
683 flag=1; 718 flag = 1;
684 } 719 }
685 720
686 if (QUERY_FLAG(op, FLAG_WIZ)) 721 if (QUERY_FLAG (op, FLAG_WIZ))
687 new_draw_info_format(NDI_UNIQUE,0, op, "- %s (%d).",query_name(tmp),tmp->count); 722 new_draw_info_format (NDI_UNIQUE, 0, op, "- %s (%d).", query_name (tmp), tmp->count);
688 else 723 else
689 new_draw_info_format(NDI_UNIQUE,0, op, "- %s.",query_name(tmp)); 724 new_draw_info_format (NDI_UNIQUE, 0, op, "- %s.", query_name (tmp));
690 725
691 if (((tmp->inv!=NULL || (tmp->head && tmp->head->inv)) && 726 if (((tmp->inv != NULL || (tmp->head && tmp->head->inv)) &&
692 (tmp->type != CONTAINER && tmp->type!=FLESH)) || QUERY_FLAG(op, FLAG_WIZ)) 727 (tmp->type != CONTAINER && tmp->type != FLESH)) || QUERY_FLAG (op, FLAG_WIZ))
693 inventory(op,tmp->head==NULL?tmp:tmp->head); 728 inventory (op, tmp->head == NULL ? tmp : tmp->head);
694 729
695 if(QUERY_FLAG(tmp, FLAG_IS_FLOOR)&&!QUERY_FLAG(op, FLAG_WIZ)) /* don't continue under the floor */ 730 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR) && !QUERY_FLAG (op, FLAG_WIZ)) /* don't continue under the floor */
696 break; 731 break;
697 } 732 }
698 733
699 if(!flag) { 734 if (!flag)
700 if(dx||dy) 735 {
736 if (dx || dy)
701 new_draw_info(NDI_UNIQUE, 0,op,"You see nothing there."); 737 new_draw_info (NDI_UNIQUE, 0, op, "You see nothing there.");
702 else 738 else
703 new_draw_info(NDI_UNIQUE, 0,op,"You see nothing."); 739 new_draw_info (NDI_UNIQUE, 0, op, "You see nothing.");
704 } 740 }
705} 741}
706 742
707 743
708 744
709/** Client wants to look at some object. Lets do so. */ 745/** Client wants to look at some object. Lets do so. */
746void
710void LookAt(char *buf, int len,player *pl) 747LookAt (char *buf, int len, player *pl)
711{ 748{
712 int dx, dy; 749 int dx, dy;
713 char *cp; 750 char *cp;
714 751
715 dx=atoi(buf); 752 dx = atoi (buf);
716 if (!(cp=strchr(buf,' '))) { 753 if (!(cp = strchr (buf, ' ')))
717 return;
718 } 754 {
755 return;
756 }
719 dy=atoi(cp); 757 dy = atoi (cp);
720 758
721 if (FABS(dx) > pl->socket.mapx / 2 || FABS(dy) > pl->socket.mapy / 2) 759 if (FABS (dx) > pl->socket->mapx / 2 || FABS (dy) > pl->socket->mapy / 2)
722 return; 760 return;
723 761
724 if(pl->blocked_los[dx + pl->socket.mapx / 2][dy + pl->socket.mapy / 2]) 762 if (pl->blocked_los[dx + pl->socket->mapx / 2][dy + pl->socket->mapy / 2])
725 return; 763 return;
726 764
727 look_at(pl->ob, dx, dy); 765 look_at (pl->ob, dx, dy);
728} 766}
729 767
730/** Move an object to a new location */ 768/** Move an object to a new location */
769void
731void esrv_move_object (object *pl, tag_t to, tag_t tag, long nrof) 770esrv_move_object (object *pl, tag_t to, tag_t tag, long nrof)
732{ 771{
733 object *op, *env; 772 object *op, *env;
734 773
735 op = esrv_get_ob_from_count(pl, tag); 774 op = esrv_get_ob_from_count (pl, tag);
736 if (!op) { 775 if (!op)
776 {
737 LOG(llevDebug, "Player '%s' tried to move an unknown object (%ld)\n", 777 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; 778 return;
751 } 779 }
780
781 if (!to)
782 { /* drop it to the ground */
783 if (op->map && !op->env)
784 return;
785
752 /* If it is an active container, then we should drop all objects 786 /* If it is an active container, then we should drop all objects
753 * in the container and not the container itself. 787 * in the container and not the container itself.
754 */ 788 */
755 if (op->inv && QUERY_FLAG(op, FLAG_APPLIED)) { 789 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED))
790 {
756 object *current, *next; 791 object *current, *next;
792
757 for (current=op->inv; current!=NULL; current=next) { 793 for (current = op->inv; current != NULL; current = next)
758 next=current->below; 794 {
795 next = current->below;
759 drop_object(pl, current, 0); 796 drop_object (pl, current, 0);
760 } 797 }
798
761 esrv_update_item(UPD_WEIGHT, pl, op); 799 esrv_update_item (UPD_WEIGHT, pl, op);
762 } 800 }
763 else { 801 else
764 drop_object (pl, op, nrof); 802 drop_object (pl, op, nrof);
765 } 803
766 return; 804 return;
767 } else if (to == pl->count) { /* pick it up to the inventory */ 805 }
806 else if (to == pl->count)
807 { /* pick it up to the inventory */
768 /* return if player has already picked it up */ 808 /* return if player has already picked it up */
769 if (op->env == pl) return; 809 if (op->env == pl)
810 return;
770 811
771 pl->contr->count = nrof; 812 pl->contr->count = nrof;
772 pick_up(pl, op); 813 pick_up (pl, op);
773 return ; 814 return;
774 } 815 }
775 /* If not dropped or picked up, we are putting it into a sack */ 816
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); 817 env = esrv_get_ob_from_count (pl, to);
782 if (!env) { 818 if (!env)
783 LOG(llevDebug, 819 {
784 "Player '%s' tried to move object to the unknown location (%d)\n", 820 LOG (llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to);
785 pl->name, to);
786 return; 821 return;
787 } 822 }
823
788 /* put_object_in_sack presumes that necessary sanity checking 824 /* put_object_in_sack presumes that necessary sanity checking
789 * has already been done (eg, it can be picked up and fits in 825 * 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 826 * 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. 827 * an make sure env is in fact a container for that matter.
792 */ 828 */
793 if (env->type == CONTAINER
794 && can_pick(pl, op) && sack_can_hold(pl, env, op, nrof)) { 829 if (env->type == CONTAINER && can_pick (pl, op) && sack_can_hold (pl, env, op, nrof))
795 put_object_in_sack (pl, env, op, nrof); 830 put_object_in_sack (pl, env, op, nrof);
796 }
797 }
798} 831}
799 832
800

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines