ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/item.C
(Generate patch)

Comparing deliantra/server/socket/item.C (file contents):
Revision 1.4 by root, Sun Sep 3 00:18:43 2006 UTC vs.
Revision 1.11 by root, Wed Dec 13 21:27:09 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines