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

Comparing deliantra/server/server/c_object.C (file contents):
Revision 1.11 by elmex, Tue Aug 29 10:51:43 2006 UTC vs.
Revision 1.25 by root, Tue Dec 12 21:39:57 2006 UTC

1/*
2 * static char *rcsid_c_object_c =
3 * "$Id: c_object.C,v 1.11 2006/08/29 10:51:43 elmex Exp $";
4 */
5/* 1/*
6 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
7 3
8 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
9 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
20 16
21 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
22 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 20
25 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>
26 22
27 Object (handling) commands 23 Object (handling) commands
28*/ 24*/
29 25
30#include <global.h> 26#include <global.h>
31#include <loader.h> 27#include <loader.h>
32#include <skills.h> 28#include <skills.h>
33#ifndef __CEXTRACT__ 29#ifndef __CEXTRACT__
34#include <sproto.h> 30# include <sproto.h>
35#endif 31#endif
36#include <living.h> 32#include <living.h>
37#include <math.h> 33#include <math.h>
34
38/* 35/*
39 * Object id parsing functions 36 * Object id parsing functions
40 */ 37 */
41 38
42#define OBLINKMALLOC(p) if(!((p)=(objectlink *)malloc(sizeof(objectlink))))\
43 fatal(OUT_OF_MEMORY);
44
45#define ADD_ITEM(NEW,COUNT)\ 39#define ADD_ITEM(NEW,COUNT)\
46 if(!first) {\ 40 if(!first) {\
47 OBLINKMALLOC(first);\ 41 first = new objectlink;\
48 last=first;\ 42 last=first;\
49 } else {\ 43 } else {\
50 OBLINKMALLOC(last->next);\ 44 last->next = new objectlink;\
51 last=last->next;\ 45 last=last->next;\
52 }\ 46 }\
53 last->next=NULL;\ 47 last->next=0;\
54 last->ob=(NEW);\ 48 last->ob=(NEW);\
55 last->id=(COUNT); 49 last->id=(COUNT);
56 50
57/** 51/**
58 * Search the inventory of 'pl' for what matches best with params. 52 * Search the inventory of 'pl' for what matches best with params.
59 * we use item_matched_string above - this gives us consistent behaviour 53 * we use item_matched_string above - this gives us consistent behaviour
60 * between many commands. Return the best match, or NULL if no match. 54 * between many commands. Return the best match, or NULL if no match.
61 * aflag is used with apply -u , and apply -a to 55 * aflag is used with apply -u , and apply -a to
62 * only unapply applied, or apply unapplied objects 56 * only unapply applied, or apply unapplied objects
63 **/ 57 **/
58static object *
64static object *find_best_apply_object_match(object *pl, const char *params, enum apply_flag aflag) 59find_best_apply_object_match (object *pl, const char *params, enum apply_flag aflag)
65{ 60{
66 object *tmp, *best=NULL; 61 object *tmp, *best = NULL;
67 int match_val=0,tmpmatch; 62 int match_val = 0, tmpmatch;
68 63
69 for (tmp=pl->inv; tmp; tmp=tmp->below) { 64 for (tmp = pl->inv; tmp; tmp = tmp->below)
65 {
70 if (tmp->invisible) continue; 66 if (tmp->invisible)
67 continue;
71 if ((tmpmatch=item_matched_string(pl, tmp, params))>match_val) { 68 if ((tmpmatch = item_matched_string (pl, tmp, params)) > match_val)
69 {
72 if ((aflag==AP_APPLY) && (QUERY_FLAG(tmp,FLAG_APPLIED))) continue; 70 if ((aflag == AP_APPLY) && (QUERY_FLAG (tmp, FLAG_APPLIED)))
71 continue;
73 if ((aflag==AP_UNAPPLY) && (!QUERY_FLAG(tmp,FLAG_APPLIED))) continue; 72 if ((aflag == AP_UNAPPLY) && (!QUERY_FLAG (tmp, FLAG_APPLIED)))
73 continue;
74 match_val=tmpmatch; 74 match_val = tmpmatch;
75 best=tmp; 75 best = tmp;
76 } 76 }
77 } 77 }
78 return best; 78 return best;
79} 79}
80 80
81/** 81/**
82 * Shortcut to find_best_apply_object_match(pl, params, AF_NULL); 82 * Shortcut to find_best_apply_object_match(pl, params, AF_NULL);
83 **/ 83 **/
84object *
84object *find_best_object_match(object *pl, const char *params) 85find_best_object_match (object *pl, const char *params)
85{ 86{
86 return find_best_apply_object_match(pl, params, AP_NULL); 87 return find_best_apply_object_match (pl, params, AP_NULL);
87} 88}
88 89
90int
89int command_uskill ( object *pl, char *params) { 91command_uskill (object *pl, char *params)
92{
90 if (!params) { 93 if (!params)
94 {
91 new_draw_info(NDI_UNIQUE, 0, pl, "Usage: use_skill <skill name>"); 95 new_draw_info (NDI_UNIQUE, 0, pl, "Usage: use_skill <skill name>");
92 return 0; 96 return 0;
93 } 97 }
94 return use_skill(pl,params); 98 return use_skill (pl, params);
95} 99}
96 100
101int
97int command_rskill ( object *pl, char *params) { 102command_rskill (object *pl, char *params)
103{
98 object *skill; 104 object *skill;
99 105
100 if (!params) { 106 if (!params)
107 {
101 new_draw_info(NDI_UNIQUE, 0, pl, "Usage: ready_skill <skill name>"); 108 new_draw_info (NDI_UNIQUE, 0, pl, "Usage: ready_skill <skill name>");
102 return 0; 109 return 0;
103 } 110 }
104 skill = find_skill_by_name(pl, params); 111 skill = find_skill_by_name (pl, params);
105 112
106 if (!skill) { 113 if (!skill)
114 {
107 new_draw_info_format(NDI_UNIQUE, 0, pl, "You have no knowledge of the skill %s", params); 115 new_draw_info_format (NDI_UNIQUE, 0, pl, "You have no knowledge of the skill %s", params);
108 return 0; 116 return 0;
109 } 117 }
110 return change_skill(pl,skill, 0); 118 return change_skill (pl, skill, 0);
111} 119}
112 120
113 121
114/* These functions (command_search, command_disarm) are really just wrappers for 122/* These functions (command_search, command_disarm) are really just wrappers for
115 * things like 'use_skill ...'). In fact, they should really be obsoleted 123 * things like 'use_skill ...'). In fact, they should really be obsoleted
116 * and replaced with those. 124 * and replaced with those.
117 */ 125 */
126int
118int command_search (object *op, char *params) { 127command_search (object *op, char *params)
128{
119 return use_skill(op, skill_names[SK_FIND_TRAPS]); 129 return use_skill (op, skill_names[SK_FIND_TRAPS]);
120} 130}
121 131
132int
122int command_disarm (object *op, char *params) { 133command_disarm (object *op, char *params)
134{
123 return use_skill(op, skill_names[SK_DISARM_TRAPS]); 135 return use_skill (op, skill_names[SK_DISARM_TRAPS]);
124} 136}
125 137
126 138
127/* A little special because we do want to pass the full params along 139/* A little special because we do want to pass the full params along
128 * as it includes the object to throw. 140 * as it includes the object to throw.
129 */ 141 */
142int
130int command_throw (object *op, char *params) 143command_throw (object *op, char *params)
131{ 144{
132 object *skop; 145 object *skop;
133 146
134 skop = find_skill_by_name(op, skill_names[SK_THROWING]); 147 skop = find_skill_by_name (op, skill_names[SK_THROWING]);
148 if (skop)
135 if (skop) return do_skill(op, op, skop, op->facing,params); 149 return do_skill (op, op, skop, op->facing, params);
136 else { 150 else
151 {
137 new_draw_info(NDI_UNIQUE, 0, op, "You have no knowledge of the skill throwing."); 152 new_draw_info (NDI_UNIQUE, 0, op, "You have no knowledge of the skill throwing.");
138 } 153 }
139 return 0; 154 return 0;
140} 155}
141 156
142 157
158int
143int command_apply (object *op, char *params) 159command_apply (object *op, char *params)
144{ 160{
145 if (!params) { 161 if (!params)
162 {
146 player_apply_below(op); 163 player_apply_below (op);
147 return 0; 164 return 0;
148 } 165 }
149 else { 166 else
167 {
150 apply_flag aflag = (apply_flag) 0; 168 apply_flag aflag = (apply_flag) 0;
151 object *inv; 169 object *inv;
152 170
153 while (*params==' ') params++; 171 while (*params == ' ')
172 params++;
154 if (!strncmp(params,"-a ",3)) { 173 if (!strncmp (params, "-a ", 3))
174 {
155 aflag=AP_APPLY; 175 aflag = AP_APPLY;
156 params+=3; 176 params += 3;
157 } 177 }
158 if (!strncmp(params,"-u ",3)) { 178 if (!strncmp (params, "-u ", 3))
179 {
159 aflag=AP_UNAPPLY; 180 aflag = AP_UNAPPLY;
181 params += 3;
182 }
183 while (*params == ' ')
160 params+=3; 184 params++;
161 }
162 while (*params==' ') params++;
163 185
164 inv=find_best_apply_object_match(op, params, aflag); 186 inv = find_best_apply_object_match (op, params, aflag);
165 if (inv) { 187 if (inv)
188 {
166 player_apply(op,inv,aflag,0); 189 player_apply (op, inv, aflag, 0);
190 }
167 } else 191 else
168 new_draw_info_format(NDI_UNIQUE, 0, op, 192 new_draw_info_format (NDI_UNIQUE, 0, op, "Could not find any match to the %s.", params);
169 "Could not find any match to the %s.",params);
170 } 193 }
171 return 0; 194 return 0;
172} 195}
173 196
174/* 197/*
175 * Check if an item op can be put into a sack. If pl exists then tell 198 * Check if an item op can be put into a sack. If pl exists then tell
178 * objects (op) we want to put in. We specify it separately instead of 201 * objects (op) we want to put in. We specify it separately instead of
179 * using op->nrof because often times, a player may have specified a 202 * using op->nrof because often times, a player may have specified a
180 * certain number of objects to drop, so we can pass that number, and 203 * certain number of objects to drop, so we can pass that number, and
181 * not need to use split_ob and stuff. 204 * not need to use split_ob and stuff.
182 */ 205 */
206int
183int sack_can_hold (object *pl, object *sack, object *op, uint32 nrof) { 207sack_can_hold (object *pl, object *sack, object *op, uint32 nrof)
208{
184 209
185 if (! QUERY_FLAG (sack, FLAG_APPLIED)) { 210 if (!QUERY_FLAG (sack, FLAG_APPLIED))
186 new_draw_info_format(NDI_UNIQUE, 0, pl, 211 {
187 "The %s is not active.", query_name(sack)); 212 new_draw_info_format (NDI_UNIQUE, 0, pl, "The %s is not active.", query_name (sack));
188 return 0; 213 return 0;
189 } 214 }
190 if (sack == op) { 215 if (sack == op)
191 new_draw_info_format(NDI_UNIQUE, 0, pl, 216 {
192 "You can't put the %s into itself.", query_name(sack)); 217 new_draw_info_format (NDI_UNIQUE, 0, pl, "You can't put the %s into itself.", query_name (sack));
193 return 0; 218 return 0;
219 }
220 if (sack->race && (sack->race != op->race || op->type == CONTAINER || (sack->stats.food && sack->stats.food != op->type)))
194 } 221 {
195 if (sack->race && (sack->race != op->race || op->type == CONTAINER
196 || (sack->stats.food && sack->stats.food != op->type))) {
197 new_draw_info_format(NDI_UNIQUE, 0, pl,
198 "You can put only %s into the %s.", sack->race, query_name(sack)); 222 new_draw_info_format (NDI_UNIQUE, 0, pl, "You can put only %s into the %s.", &sack->race, query_name (sack));
199 return 0; 223 return 0;
200 } 224 }
201 if (op->type == SPECIAL_KEY && sack->slaying && op->slaying) { 225 if (op->type == SPECIAL_KEY && sack->slaying && op->slaying)
202 new_draw_info_format(NDI_UNIQUE, 0, pl, 226 {
203 "You can't put the key into %s.", query_name(sack)); 227 new_draw_info_format (NDI_UNIQUE, 0, pl, "You can't put the key into %s.", query_name (sack));
204 return 0; 228 return 0;
205 } 229 }
206 if (sack->weight_limit && sack->carrying + (nrof ? nrof : 1) * 230 if (sack->weight_limit && (sint32) (sack->carrying + (nrof ? nrof : 1) *
207 (op->weight + (op->type==CONTAINER?(op->carrying*op->stats.Str):0)) 231 (op->weight + (op->type == CONTAINER ? (op->carrying * op->stats.Str) : 0))
208 * (100 - sack->stats.Str) / 100 > sack->weight_limit) { 232 * (100 - sack->stats.Str) / 100) > sack->weight_limit)
209 new_draw_info_format(NDI_UNIQUE, 0, pl, 233 {
210 "That won't fit in the %s!", query_name(sack)); 234 new_draw_info_format (NDI_UNIQUE, 0, pl, "That won't fit in the %s!", query_name (sack));
211 return 0; 235 return 0;
212 } 236 }
213 /* All other checks pass, must be OK */ 237 /* All other checks pass, must be OK */
214 return 1; 238 return 1;
215} 239}
216 240
217/* Pick up commands follow */ 241/* Pick up commands follow */
242
218/* pl = player (not always - monsters can use this now) 243/* pl = player (not always - monsters can use this now)
219 * op is the object to put tmp into, 244 * op is the object to put tmp into,
220 * tmp is the object to pick up, nrof is the number to 245 * tmp is the object to pick up, nrof is the number to
221 * pick up (0 means all of them) 246 * pick up (0 means all of them)
222 */ 247 */
248static void
223static void pick_up_object (object *pl, object *op, object *tmp, int nrof) 249pick_up_object (object *pl, object *op, object *tmp, int nrof)
224{ 250{
225 /* buf needs to be big (more than 256 chars) because you can get 251 /* buf needs to be big (more than 256 chars) because you can get
226 * very long item names. 252 * very long item names.
227 */ 253 */
228 char buf[HUGE_BUF]; 254 char buf[HUGE_BUF];
229 object *env=tmp->env; 255 object *env = tmp->env;
230 uint32 weight, effective_weight_limit; 256 uint32 weight, effective_weight_limit;
231 int tmp_nrof = tmp->nrof ? tmp->nrof : 1; 257 int tmp_nrof = tmp->nrof ? tmp->nrof : 1;
232 258
233 /* IF the player is flying & trying to take the item out of a container 259 /* IF the player is flying & trying to take the item out of a container
234 * that is in his inventory, let him. tmp->env points to the container 260 * that is in his inventory, let him. tmp->env points to the container
235 * (sack, luggage, etc), tmp->env->env then points to the player (nested 261 * (sack, luggage, etc), tmp->env->env then points to the player (nested
236 * containers not allowed as of now) 262 * containers not allowed as of now)
237 */ 263 */
238 if((pl->move_type & MOVE_FLYING) && !QUERY_FLAG(pl, FLAG_WIZ) && 264 if ((pl->move_type & MOVE_FLYING) && !QUERY_FLAG (pl, FLAG_WIZ) && is_player_inv (tmp) != pl)
239 is_player_inv(tmp)!=pl) { 265 {
240 new_draw_info(NDI_UNIQUE, 0,pl, "You are levitating, you can't reach the ground!"); 266 new_draw_info (NDI_UNIQUE, 0, pl, "You are levitating, you can't reach the ground!");
241 return; 267 return;
242 } 268 }
269
243 if (QUERY_FLAG (tmp, FLAG_NO_DROP)) 270 if (QUERY_FLAG (tmp, FLAG_NO_DROP))
244 return; 271 return;
272
245 if(QUERY_FLAG(tmp,FLAG_WAS_WIZ) && !QUERY_FLAG(pl, FLAG_WAS_WIZ)) { 273 if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ))
274 {
246 new_draw_info(NDI_UNIQUE, 0,pl, "The object disappears in a puff of smoke!"); 275 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff of smoke!");
247 new_draw_info(NDI_UNIQUE, 0,pl, "It must have been an illusion."); 276 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion.");
277
278 if (pl->type == PLAYER)
248 if (pl->type==PLAYER) esrv_del_item (pl->contr, tmp->count); 279 esrv_del_item (pl->contr, tmp->count);
249 if ( ! QUERY_FLAG (tmp, FLAG_REMOVED)) 280
250 remove_ob (tmp); 281 tmp->destroy ();
251 free_object(tmp);
252 return; 282 return;
253 }
254 283 }
284
255 if (nrof > tmp_nrof || nrof == 0) 285 if (nrof > tmp_nrof || nrof == 0)
256 nrof = tmp_nrof; 286 nrof = tmp_nrof;
287
257 /* Figure out how much weight this object will add to the player */ 288 /* Figure out how much weight this object will add to the player */
258 weight = tmp->weight * nrof; 289 weight = tmp->weight * nrof;
290 if (tmp->inv)
259 if (tmp->inv) weight += tmp->carrying * (100 - tmp->stats.Str) / 100; 291 weight += tmp->carrying * (100 - tmp->stats.Str) / 100;
292
260 if (pl->stats.Str <= MAX_STAT) 293 if (pl->stats.Str <= MAX_STAT)
261 effective_weight_limit = weight_limit[pl->stats.Str]; 294 effective_weight_limit = weight_limit[pl->stats.Str];
262 else 295 else
263 effective_weight_limit = weight_limit[MAX_STAT]; 296 effective_weight_limit = weight_limit[MAX_STAT];
297
264 if ((pl->weight + pl->carrying + weight) > effective_weight_limit) { 298 if ((pl->weight + pl->carrying + weight) > effective_weight_limit)
299 {
265 new_draw_info(0, 0,pl,"That item is too heavy for you to pick up."); 300 new_draw_info (0, 0, pl, "That item is too heavy for you to pick up.");
266 return; 301 return;
267 } 302 }
303
268 if (settings.real_wiz == FALSE && QUERY_FLAG(pl, FLAG_WAS_WIZ)) 304 if (settings.real_wiz == FALSE && QUERY_FLAG (pl, FLAG_WAS_WIZ))
269 SET_FLAG(tmp, FLAG_WAS_WIZ); 305 SET_FLAG (tmp, FLAG_WAS_WIZ);
306
270 if (nrof != tmp_nrof) { 307 if (nrof != tmp_nrof)
308 {
271 object *tmp2 = tmp; 309 object *tmp2 = tmp;
272 tag_t tmp2_tag = tmp2->count; 310
273 tmp = get_split_ob (tmp, nrof); 311 tmp = get_split_ob (tmp, nrof);
274 if(!tmp) { 312 if (!tmp)
313 {
275 new_draw_info(NDI_UNIQUE, 0,pl, errmsg); 314 new_draw_info (NDI_UNIQUE, 0, pl, errmsg);
276 return; 315 return;
277 } 316 }
317
278 /* Tell a client what happened rest of objects */ 318 /* Tell a client what happened rest of objects */
279 if (pl->type == PLAYER) { 319 if (pl->type == PLAYER)
280 if (was_destroyed (tmp2, tmp2_tag)) 320 {
321 if (tmp2->destroyed ())
281 esrv_del_item (pl->contr, tmp2_tag); 322 esrv_del_item (pl->contr, tmp2->count);
282 else 323 else
283 esrv_send_item (pl, tmp2); 324 esrv_send_item (pl, tmp2);
284 } 325 }
285 } else { 326 }
327 else
328 {
286 /* If the object is in a container, send a delete to the client. 329 /* If the object is in a container, send a delete to the client.
287 * - we are moving all the items from the container to elsewhere, 330 * - we are moving all the items from the container to elsewhere,
288 * so it needs to be deleted. 331 * so it needs to be deleted.
289 */ 332 */
290 if ( ! QUERY_FLAG (tmp, FLAG_REMOVED)) { 333 if (!QUERY_FLAG (tmp, FLAG_REMOVED))
334 {
291 if (tmp->env && pl->type==PLAYER) 335 if (tmp->env && pl->type == PLAYER)
292 esrv_del_item (pl->contr, tmp->count); 336 esrv_del_item (pl->contr, tmp->count);
293 remove_ob(tmp); /* Unlink it */ 337 tmp->remove (); /* Unlink it */
294 } 338 }
295 } 339 }
296 if(QUERY_FLAG(tmp, FLAG_UNPAID)) 340 if (QUERY_FLAG (tmp, FLAG_UNPAID))
297 (void) sprintf(buf,"%s will cost you %s.", query_name(tmp), 341 (void) sprintf (buf, "%s will cost you %s.", query_name (tmp), query_cost_string (tmp, pl, F_BUY | F_SHOP));
298 query_cost_string(tmp,pl,F_BUY | F_SHOP));
299 else 342 else
300 (void) sprintf(buf,"You pick up the %s.", query_name(tmp)); 343 (void) sprintf (buf, "You pick up the %s.", query_name (tmp));
301 new_draw_info(NDI_UNIQUE, 0,pl,buf); 344 new_draw_info (NDI_UNIQUE, 0, pl, buf);
302 345
303 tmp = insert_ob_in_ob(tmp, op); 346 tmp = insert_ob_in_ob (tmp, op);
304 347
305 /* All the stuff below deals with client/server code, and is only 348 /* All the stuff below deals with client/server code, and is only
306 * usable by players 349 * usable by players
307 */ 350 */
308 if(pl->type!=PLAYER) return; 351 if (pl->type != PLAYER)
352 return;
309 353
310 esrv_send_item (pl, tmp); 354 esrv_send_item (pl, tmp);
311 /* These are needed to update the weight for the container we 355 /* These are needed to update the weight for the container we
312 * are putting the object in. 356 * are putting the object in.
313 */ 357 */
314 if (op!=pl) { 358 if (op != pl)
359 {
315 esrv_update_item (UPD_WEIGHT, pl, op); 360 esrv_update_item (UPD_WEIGHT, pl, op);
316 esrv_send_item (pl, pl); 361 esrv_send_item (pl, pl);
317 } 362 }
318 363
319 /* Update the container the object was in */ 364 /* Update the container the object was in */
320 if (env && env!=pl && env!=op) esrv_update_item (UPD_WEIGHT, pl, env); 365 if (env && env != pl && env != op)
366 esrv_update_item (UPD_WEIGHT, pl, env);
321} 367}
322 368
323
324void pick_up(object *op,object *alt)
325/* modified slightly to allow monsters use this -b.t. 5-31-95 */ 369/* modified slightly to allow monsters use this -b.t. 5-31-95 */
370void
371pick_up (object *op, object *alt)
326{ 372{
327 int need_fix_tmp = 0; 373 int need_fix_tmp = 0;
328 object *tmp=NULL; 374 object *tmp = NULL;
329 mapstruct *tmp_map=NULL; 375 maptile *tmp_map = NULL;
330 int count; 376 int count;
331 tag_t tag;
332 377
333 /* Decide which object to pick. */ 378 /* Decide which object to pick. */
334 if (alt) 379 if (alt)
335 { 380 {
336 if ( ! can_pick (op, alt)) { 381 if (!can_pick (op, alt))
382 {
337 new_draw_info_format (NDI_UNIQUE, 0, op, "You can't pick up the %s.", 383 new_draw_info_format (NDI_UNIQUE, 0, op, "You can't pick up the %s.", &alt->name);
338 alt->name);
339 goto leave; 384 goto leave;
340 } 385 }
341 tmp = alt; 386 tmp = alt;
342 } 387 }
343 else 388 else
344 { 389 {
345 if (op->below == NULL || ! can_pick (op, op->below)) { 390 if (op->below == NULL || !can_pick (op, op->below))
346 new_draw_info (NDI_UNIQUE, 0, op, 391 {
347 "There is nothing to pick up here."); 392 new_draw_info (NDI_UNIQUE, 0, op, "There is nothing to pick up here.");
348 goto leave; 393 goto leave;
349 } 394 }
395
350 tmp = op->below; 396 tmp = op->below;
351 } 397 }
352 398
353 /* Try to catch it. */ 399 /* Try to catch it. */
354 tmp_map = tmp->map; 400 tmp_map = tmp->map;
355 tmp = stop_item (tmp); 401 tmp = stop_item (tmp);
356 if (tmp == NULL) 402 if (tmp == NULL)
403 goto leave;
404 need_fix_tmp = 1;
405 if (!can_pick (op, tmp))
406 goto leave;
407
408 if (op->type == PLAYER)
409 {
410 count = op->contr->count;
411 if (count == 0)
412 count = tmp->nrof;
413 }
414 else
415 count = tmp->nrof;
416
417 /* container is open, so use it */
418 if (op->container)
419 {
420 alt = op->container;
421 if (alt != tmp->env && !sack_can_hold (op, alt, tmp, count))
357 goto leave; 422 goto leave;
358 need_fix_tmp = 1;
359 if ( ! can_pick (op, tmp))
360 goto leave;
361
362 if (op->type==PLAYER) {
363 count=op->contr->count;
364 if (count==0) count = tmp->nrof;
365 } 423 }
366 else 424 else
367 count=tmp->nrof; 425 { /* non container pickup */
426 for (alt = op->inv; alt; alt = alt->below)
427 if (alt->type == CONTAINER && QUERY_FLAG (alt, FLAG_APPLIED) &&
428 alt->race && alt->race == tmp->race && sack_can_hold (NULL, alt, tmp, count))
429 break; /* perfect match */
368 430
369 /* container is open, so use it */ 431 if (!alt)
370 if (op->container) {
371 alt = op->container;
372 if (alt != tmp->env && !sack_can_hold (op, alt, tmp,count))
373 goto leave;
374 } else { /* non container pickup */
375 for (alt=op->inv; alt; alt=alt->below) 432 for (alt = op->inv; alt; alt = alt->below)
376 if (alt->type==CONTAINER && QUERY_FLAG(alt, FLAG_APPLIED) && 433 if (alt->type == CONTAINER && QUERY_FLAG (alt, FLAG_APPLIED) && sack_can_hold (NULL, alt, tmp, count))
377 alt->race && alt->race==tmp->race && 434 break; /* General container comes next */
378 sack_can_hold (NULL, alt, tmp,count))
379 break; /* perfect match */
380
381 if (!alt) 435 if (!alt)
382 for (alt=op->inv; alt; alt=alt->below)
383 if (alt->type==CONTAINER && QUERY_FLAG(alt, FLAG_APPLIED) &&
384 sack_can_hold (NULL, alt, tmp,count))
385 break; /* General container comes next */
386 if (!alt)
387 alt = op; /* No free containers */ 436 alt = op; /* No free containers */
388 } 437 }
438
389 if(tmp->env == alt) { 439 if (tmp->env == alt)
440 {
390 /* here it could be possible to check rent, 441 /* here it could be possible to check rent,
391 * if someone wants to implement it 442 * if someone wants to implement it
392 */ 443 */
393 alt = op; 444 alt = op;
394 } 445 }
395#ifdef PICKUP_DEBUG 446#ifdef PICKUP_DEBUG
396 LOG(llevDebug, "Pick_up(): %s picks %s (%d) and inserts it %s.\n", op->name, tmp->name, op->contr->count, alt->name); 447 LOG (llevDebug, "Pick_up(): %s picks %s (%d) and inserts it %s.\n", op->name, tmp->name, op->contr->count, alt->name);
397#endif 448#endif
398 449
399 /* startequip items are not allowed to be put into containers: */ 450 /* startequip items are not allowed to be put into containers: */
400 if (op->type == PLAYER && alt->type == CONTAINER 451 if (op->type == PLAYER && alt->type == CONTAINER && QUERY_FLAG (tmp, FLAG_STARTEQUIP))
401 && QUERY_FLAG (tmp, FLAG_STARTEQUIP))
402 { 452 {
403 new_draw_info (NDI_UNIQUE, 0, op, 453 new_draw_info (NDI_UNIQUE, 0, op, "This object cannot be put into containers!");
404 "This object cannot be put into containers!");
405 goto leave; 454 goto leave;
406 } 455 }
407 456
408 tag = tmp->count;
409 pick_up_object (op, alt, tmp, count); 457 pick_up_object (op, alt, tmp, count);
458
410 if (was_destroyed (tmp, tag) || tmp->env) 459 if (tmp->destroyed () || tmp->env)
411 need_fix_tmp = 0; 460 need_fix_tmp = 0;
461
412 if (op->type == PLAYER) 462 if (op->type == PLAYER)
413 op->contr->count=0; 463 op->contr->count = 0;
464
414 goto leave; 465 goto leave;
415 466
416 leave: 467leave:
417 if (need_fix_tmp) 468 if (need_fix_tmp)
418 fix_stopped_item (tmp, tmp_map, op); 469 fix_stopped_item (tmp, tmp_map, op);
419} 470}
420 471
421 472
422/* This takes (picks up) and item. op is the player 473/* This takes (picks up) and item. op is the player
423 * who issued the command. params is a string to 474 * who issued the command. params is a string to
424 * match against the item name. Basically, always 475 * match against the item name. Basically, always
425 * returns zero, but that should be improved. 476 * returns zero, but that should be improved.
426 */ 477 */
478int
427int command_take (object *op, char *params) 479command_take (object *op, char *params)
428{ 480{
429 object *tmp, *next; 481 object *tmp, *next;
430 482
431 if (op->container) 483 if (op->container)
432 tmp=op->container->inv; 484 tmp = op->container->inv;
433 else { 485 else
486 {
434 tmp=op->above; 487 tmp = op->above;
488 if (tmp)
435 if (tmp) while (tmp->above) { 489 while (tmp->above)
436 tmp=tmp->above; 490 tmp = tmp->above;
437 } 491
438 if (!tmp) 492 if (!tmp)
439 tmp=op->below; 493 tmp = op->below;
440 } 494 }
441 495
442 if (tmp==NULL) { 496 if (tmp == NULL)
497 {
443 new_draw_info(NDI_UNIQUE, 0,op,"Nothing to take!"); 498 new_draw_info (NDI_UNIQUE, 0, op, "Nothing to take!");
444 return 0; 499 return 0;
445 } 500 }
446 501
447 /* Makes processing easier */ 502 /* Makes processing easier */
448 if (params && *params=='\0') params=NULL; 503 if (params && *params == '\0')
504 params = NULL;
449 505
450 while (tmp) { 506 while (tmp)
507 {
451 next=tmp->below; 508 next = tmp->below;
452 509
453 if (tmp->invisible) { 510 if (tmp->invisible)
511 {
454 tmp=next; 512 tmp = next;
455 continue; 513 continue;
456 } 514 }
457 /* This following two if and else if could be merged into line 515 /* This following two if and else if could be merged into line
458 * but that probably will make it more difficult to read, and 516 * but that probably will make it more difficult to read, and
459 * not make it any more efficient 517 * not make it any more efficient
460 */ 518 */
461 if (params && item_matched_string(op, tmp, params)) { 519 if (params && item_matched_string (op, tmp, params))
520 {
462 pick_up(op, tmp); 521 pick_up (op, tmp);
463 } 522 }
464 else if (can_pick(op, tmp) && !params) { 523 else if (can_pick (op, tmp) && !params)
524 {
465 pick_up(op,tmp); 525 pick_up (op, tmp);
526 break;
527 }
528 tmp = next;
529 /* Might as well just skip over the player immediately -
530 * we know it can't be picked up
531 */
532 if (tmp == op)
533 tmp = tmp->below;
534 }
535 if (!params && !tmp)
536 {
537 for (tmp = op->below; tmp != NULL; tmp = tmp->next)
538 if (!tmp->invisible)
539 {
540 char buf[MAX_BUF];
541
542 sprintf (buf, "You can't pick up a %s.", &tmp->name);
543 new_draw_info (NDI_UNIQUE, 0, op, buf);
466 break; 544 break;
467 }
468 tmp=next;
469 /* Might as well just skip over the player immediately -
470 * we know it can't be picked up
471 */
472 if (tmp == op) tmp=tmp->below;
473 }
474 if (!params && !tmp) {
475 for (tmp=op->below; tmp!=NULL; tmp=tmp->next)
476 if (!tmp->invisible) {
477 char buf[MAX_BUF];
478 sprintf(buf,"You can't pick up a %s.",
479 tmp->name? tmp->name:"null");
480 new_draw_info(NDI_UNIQUE, 0,op, buf);
481 break;
482 } 545 }
546 if (!tmp)
483 if (!tmp) new_draw_info(NDI_UNIQUE, 0,op, "There is nothing to pick up."); 547 new_draw_info (NDI_UNIQUE, 0, op, "There is nothing to pick up.");
484 } 548 }
485 return 0; 549 return 0;
486} 550}
487 551
488 552
489/* 553/*
490 * This function was part of drop, now is own function. 554 * This function was part of drop, now is own function.
491 * Player 'op' tries to put object 'tmp' into sack 'sack', 555 * Player 'op' tries to put object 'tmp' into sack 'sack',
492 * if nrof is non zero, then nrof objects is tried to put into sack. 556 * if nrof is non zero, then nrof objects is tried to put into sack.
493 * Note that the 'sack' in question can now be a transport, 557 * Note that the 'sack' in question can now be a transport,
494 * so this function isn't named very good anymore. 558 * so this function isn't named very good anymore.
495 */ 559 */
560void
496void put_object_in_sack (object *op, object *sack, object *tmp, uint32 nrof) 561put_object_in_sack (object *op, object *sack, object *tmp, uint32 nrof)
497{ 562{
498 tag_t tmp_tag, tmp2_tag;
499 object *tmp2, *sack2; 563 object *tmp2, *sack2;
500 char buf[MAX_BUF]; 564 char buf[MAX_BUF];
501 565
502 if (sack==tmp) return; /* Can't put an object in itself */ 566 if (sack == tmp)
567 return; /* Can't put an object in itself */
568
503 if (QUERY_FLAG(tmp,FLAG_STARTEQUIP)) { 569 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP))
504 new_draw_info_format(NDI_UNIQUE, 0,op, 570 {
505 "You cannot put the %s in the %s.", query_name(tmp), 571 new_draw_info_format (NDI_UNIQUE, 0, op, "You cannot put the %s in the %s.", query_name (tmp), query_name (sack));
506 query_name(sack));
507 return; 572 return;
508 } 573 }
574
509 if (tmp->type == CONTAINER && tmp->inv) { 575 if (tmp->type == CONTAINER && tmp->inv)
576 {
510 577
511 /* Eneq(@csd.uu.se): If the object to be dropped is a container 578 /* Eneq(@csd.uu.se): If the object to be dropped is a container
512 * we instead move the contents of that container into the active 579 * we instead move the contents of that container into the active
513 * container, this is only done if the object has something in it. 580 * container, this is only done if the object has something in it.
514 */ 581 */
515 sack2 = tmp; 582 sack2 = tmp;
516 new_draw_info_format(NDI_UNIQUE, 0,op, "You move the items from %s into %s.", 583 new_draw_info_format (NDI_UNIQUE, 0, op, "You move the items from %s into %s.", query_name (tmp), query_name (sack));
517 query_name(tmp), query_name(sack)); 584
518 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp) { 585 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp)
586 {
519 tmp = tmp2->below; 587 tmp = tmp2->below;
588
520 if ((sack->type == CONTAINER && sack_can_hold(op, op->container, tmp2,tmp2->nrof))) { 589 if ((sack->type == CONTAINER && sack_can_hold (op, op->container, tmp2, tmp2->nrof)))
590 {
521 put_object_in_sack (op, sack, tmp2, 0); 591 put_object_in_sack (op, sack, tmp2, 0);
522 } else {
523 sprintf(buf,"Your %s fills up.", query_name(sack));
524 new_draw_info(NDI_UNIQUE, 0,op, buf);
525 break;
526 } 592 }
593 else
594 {
595 sprintf (buf, "Your %s fills up.", query_name (sack));
596 new_draw_info (NDI_UNIQUE, 0, op, buf);
597 break;
527 } 598 }
599 }
600
528 esrv_update_item (UPD_WEIGHT, op, sack2); 601 esrv_update_item (UPD_WEIGHT, op, sack2);
529 return; 602 return;
530 } 603 }
531 604
532 /* Don't worry about this for containers - our caller should have 605 /* Don't worry about this for containers - our caller should have
533 * already checked this. 606 * already checked this.
534 */ 607 */
535 if ((sack->type == CONTAINER) && !sack_can_hold (op, sack, tmp,(nrof?nrof:tmp->nrof))) 608 if ((sack->type == CONTAINER) && !sack_can_hold (op, sack, tmp, (nrof ? nrof : tmp->nrof)))
536 return; 609 return;
537 610
538 if(QUERY_FLAG(tmp, FLAG_APPLIED)) { 611 if (QUERY_FLAG (tmp, FLAG_APPLIED))
539 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE)) 612 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE))
540 return; 613 return;
541 }
542 614
543 /* we want to put some portion of the item into the container */ 615 /* we want to put some portion of the item into the container */
544 if (nrof && tmp->nrof != nrof) { 616 if (nrof && tmp->nrof != nrof)
617 {
545 object *tmp2 = tmp; 618 object *tmp2 = tmp;
546 tmp2_tag = tmp2->count; 619
547 tmp = get_split_ob (tmp, nrof); 620 tmp = get_split_ob (tmp, nrof);
548 621
549 if(!tmp) { 622 if (!tmp)
623 {
550 new_draw_info(NDI_UNIQUE, 0,op, errmsg); 624 new_draw_info (NDI_UNIQUE, 0, op, errmsg);
551 return; 625 return;
552 } 626 }
553 /* Tell a client what happened other objects */ 627 /* Tell a client what happened other objects */
554 if (was_destroyed (tmp2, tmp2_tag)) 628 if (tmp2->destroyed ())
555 esrv_del_item (op->contr, tmp2_tag); 629 esrv_del_item (op->contr, tmp2->count);
556 else /* this can proably be replaced with an update */ 630 else /* this can proably be replaced with an update */
557 esrv_send_item (op, tmp2); 631 esrv_send_item (op, tmp2);
632 }
558 } else 633 else
559 remove_ob(tmp); 634 tmp->remove ();
560 635
561 new_draw_info_format(NDI_UNIQUE, 0,op, "You put the %s in %s.", 636 new_draw_info_format (NDI_UNIQUE, 0, op, "You put the %s in %s.", query_name (tmp), query_name (sack));
562 query_name(tmp), query_name(sack));
563 tmp_tag = tmp->count;
564 tmp2 = insert_ob_in_ob(tmp, sack); 637 tmp2 = insert_ob_in_ob (tmp, sack);
565 fix_player(op); /* This is overkill, fix_player() is called somewhere */ 638 fix_player (op); /* This is overkill, fix_player() is called somewhere */
566 /* in object.c */ 639 /* in object.c */
567 640
568 /* If an object merged (and thus, different object), we need to 641 /* If an object merged (and thus, different object), we need to
569 * delete the original. 642 * delete the original.
570 */ 643 */
571 if (tmp2 != tmp) 644 if (tmp2 != tmp)
572 esrv_del_item (op->contr, tmp_tag); 645 esrv_del_item (op->contr, tmp->count);
573 646
574 esrv_send_item (op, tmp2); 647 esrv_send_item (op, tmp2);
575 648
576 /* update the sacks weight */ 649 /* update the sacks weight */
577 esrv_update_item (UPD_WEIGHT, op, sack); 650 esrv_update_item (UPD_WEIGHT, op, sack);
578} 651}
579 652
580/* 653/*
581 * This function was part of drop, now is own function. 654 * This function was part of drop, now is own function.
582 * Player 'op' tries to drop object 'tmp', if tmp is non zero, then 655 * Player 'op' tries to drop object 'tmp', if tmp is non zero, then
583 * nrof objects is tried to dropped. 656 * nrof objects is tried to dropped.
584 * This is used when dropping objects onto the floor. 657 * This is used when dropping objects onto the floor.
585 */ 658 */
586void 659void
587drop_object (object * op, object * tmp, uint32 nrof) 660drop_object (object *op, object *tmp, uint32 nrof)
588{ 661{
589 char buf[MAX_BUF]; 662 char buf[MAX_BUF];
590 object *floor; 663 object *floor;
591 664
592 if (QUERY_FLAG (tmp, FLAG_NO_DROP)) 665 if (QUERY_FLAG (tmp, FLAG_NO_DROP))
593 return; 666 return;
594 667
595 if (QUERY_FLAG (tmp, FLAG_APPLIED)) 668 if (QUERY_FLAG (tmp, FLAG_APPLIED))
596 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE)) 669 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE))
597 return; /* can't unapply it */ 670 return; /* can't unapply it */
598 671
599 /* We are only dropping some of the items. We split the current objec 672 /* We are only dropping some of the items. We split the current object
600 * off 673 * off
601 */ 674 */
602 if (nrof && tmp->nrof != nrof) 675 if (nrof && tmp->nrof != nrof)
603 { 676 {
604 object *tmp2 = tmp; 677 object *tmp2 = tmp;
605 tag_t tmp2_tag = tmp2->count; 678
606 tmp = get_split_ob (tmp, nrof); 679 tmp = get_split_ob (tmp, nrof);
607 if (!tmp) 680 if (!tmp)
608 { 681 {
609 new_draw_info (NDI_UNIQUE, 0, op, errmsg); 682 new_draw_info (NDI_UNIQUE, 0, op, errmsg);
610 return; 683 return;
612 /* Tell a client what happened rest of objects. tmp2 is now the 685 /* Tell a client what happened rest of objects. tmp2 is now the
613 * original object 686 * original object
614 */ 687 */
615 if (op->type == PLAYER) 688 if (op->type == PLAYER)
616 { 689 {
617 if (was_destroyed (tmp2, tmp2_tag)) 690 if (tmp2->destroyed ())
618 esrv_del_item (op->contr, tmp2_tag); 691 esrv_del_item (op->contr, tmp2->count);
619 else 692 else
620 esrv_send_item (op, tmp2); 693 esrv_send_item (op, tmp2);
621 } 694 }
622 } 695 }
623 else 696 else
624 remove_ob (tmp); 697 tmp->remove ();
625 698
626 if (INVOKE_OBJECT (DROP, tmp, ARG_OBJECT (op))) 699 if (INVOKE_OBJECT (DROP, tmp, ARG_OBJECT (op)))
627 return; 700 return;
628 701
629 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP)) 702 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP))
630 { 703 {
631 sprintf (buf, "You drop the %s.", query_name (tmp)); 704 sprintf (buf, "You drop the %s.", query_name (tmp));
632 new_draw_info (NDI_UNIQUE, 0, op, buf); 705 new_draw_info (NDI_UNIQUE, 0, op, buf);
633 new_draw_info (NDI_UNIQUE, 0, op, 706 new_draw_info (NDI_UNIQUE, 0, op, "The gods who lent it to you retrieves it.");
634 "The gods who lent it to you retrieves it.");
635 if (op->type == PLAYER) 707 if (op->type == PLAYER)
636 esrv_del_item (op->contr, tmp->count); 708 esrv_del_item (op->contr, tmp->count);
637 free_object (tmp); 709 tmp->destroy ();
638 fix_player (op); 710 fix_player (op);
639 return; 711 return;
640 } 712 }
641 713
642/* If SAVE_INTERVAL is commented out, we never want to save 714/* If SAVE_INTERVAL is commented out, we never want to save
646 /* I'm not sure why there is a value check - since the save 718 /* I'm not sure why there is a value check - since the save
647 * is done every SAVE_INTERVAL seconds, why care the value 719 * is done every SAVE_INTERVAL seconds, why care the value
648 * of what he is dropping? 720 * of what he is dropping?
649 */ 721 */
650 if (op->type == PLAYER && !QUERY_FLAG (tmp, FLAG_UNPAID) && 722 if (op->type == PLAYER && !QUERY_FLAG (tmp, FLAG_UNPAID) &&
651 (tmp->nrof ? tmp->value * tmp->nrof : tmp->value > 2000) && 723 (tmp->nrof ? tmp->value * tmp->nrof : tmp->value > 2000) && (op->contr->last_save_time + SAVE_INTERVAL) <= time (NULL))
652 (op->contr->last_save_time + SAVE_INTERVAL) <= time (NULL))
653 { 724 {
654 save_player (op, 1); 725 save_player (op, 1);
655 op->contr->last_save_time = time (NULL); 726 op->contr->last_save_time = time (NULL);
656 } 727 }
657#endif /* SAVE_INTERVAL */ 728#endif /* SAVE_INTERVAL */
660 esrv_del_item (op->contr, tmp->count); 731 esrv_del_item (op->contr, tmp->count);
661 732
662 /* Call this before we update the various windows/players. At least 733 /* Call this before we update the various windows/players. At least
663 * that we, we know the weight is correct. 734 * that we, we know the weight is correct.
664 */ 735 */
665 fix_player (op); /* This is overkill, fix_player() is called somewhere */ 736 fix_player (op); /* This is overkill, fix_player() is called somewhere */
666 /* in object.c */ 737 /* in object.c */
667 738
668 if (op->type == PLAYER) 739 if (op->type == PLAYER)
669 { 740 {
670 op->contr->socket.update_look = 1; 741 op->contr->socket.update_look = 1;
671 /* Need to update the weight for the player */ 742 /* Need to update the weight for the player */
674 745
675 for (floor = get_map_ob (op->map, op->x, op->y); floor; floor = floor->above) 746 for (floor = get_map_ob (op->map, op->x, op->y); floor; floor = floor->above)
676 if (INVOKE_OBJECT (DROP_ON, floor, ARG_OBJECT (tmp), ARG_OBJECT (op))) 747 if (INVOKE_OBJECT (DROP_ON, floor, ARG_OBJECT (tmp), ARG_OBJECT (op)))
677 return; 748 return;
678 749
679 if (is_in_shop (op) 750 if (is_in_shop (op) && !QUERY_FLAG (tmp, FLAG_UNPAID) && tmp->type != MONEY)
680 && !QUERY_FLAG (tmp, FLAG_UNPAID)
681 && tmp->type != MONEY)
682 sell_item (tmp, op); 751 sell_item (tmp, op);
683 752
684 tmp->x = op->x; 753 tmp->x = op->x;
685 tmp->y = op->y; 754 tmp->y = op->y;
686 755
687 insert_ob_in_map (tmp, op->map, op, INS_BELOW_ORIGINATOR); 756 insert_ob_in_map (tmp, op->map, op, INS_BELOW_ORIGINATOR);
688} 757}
689 758
759void
690void drop(object *op, object *tmp) 760drop (object *op, object *tmp)
691{ 761{
692 /* Hopeful fix for disappearing objects when dropping from a container - 762 /* Hopeful fix for disappearing objects when dropping from a container -
693 * somehow, players get an invisible object in the container, and the 763 * somehow, players get an invisible object in the container, and the
694 * old logic would skip over invisible objects - works fine for the 764 * old logic would skip over invisible objects - works fine for the
695 * playes inventory, but drop inventory wants to use the next value. 765 * playes inventory, but drop inventory wants to use the next value.
696 */ 766 */
697 if (tmp->invisible) { 767 if (tmp->invisible)
768 {
698 /* if the following is the case, it must be in an container. */ 769 /* if the following is the case, it must be in an container. */
699 if (tmp->env && tmp->env->type != PLAYER) { 770 if (tmp->env && tmp->env->type != PLAYER)
771 {
700 /* Just toss the object - probably shouldn't be hanging 772 /* Just toss the object - probably shouldn't be hanging
701 * around anyways 773 * around anyways
702 */ 774 */
703 remove_ob(tmp); 775 tmp->remove ();
704 free_object(tmp); 776 tmp->destroy ();
705 return; 777 return;
778 }
706 } else { 779 else
780 {
707 while(tmp!=NULL && tmp->invisible) 781 while (tmp != NULL && tmp->invisible)
708 tmp=tmp->below; 782 tmp = tmp->below;
709 } 783 }
710 } 784 }
711 785
712 if (tmp==NULL) { 786 if (tmp == NULL)
787 {
713 new_draw_info(NDI_UNIQUE, 0,op,"You don't have anything to drop."); 788 new_draw_info (NDI_UNIQUE, 0, op, "You don't have anything to drop.");
714 return; 789 return;
715 } 790 }
716 if (QUERY_FLAG(tmp, FLAG_INV_LOCKED)) { 791 if (QUERY_FLAG (tmp, FLAG_INV_LOCKED))
792 {
717 new_draw_info(NDI_UNIQUE, 0,op,"This item is locked"); 793 new_draw_info (NDI_UNIQUE, 0, op, "This item is locked");
718 return; 794 return;
719 } 795 }
720 if (QUERY_FLAG(tmp, FLAG_NO_DROP)) { 796 if (QUERY_FLAG (tmp, FLAG_NO_DROP))
797 {
721#if 0 798#if 0
722 /* Eneq(@csd.uu.se): Objects with NO_DROP defined can't be dropped. */ 799 /* Eneq(@csd.uu.se): Objects with NO_DROP defined can't be dropped. */
723 new_draw_info(NDI_UNIQUE, 0,op, "This item can't be dropped."); 800 new_draw_info (NDI_UNIQUE, 0, op, "This item can't be dropped.");
724#endif 801#endif
725 return; 802 return;
726 } 803 }
727 804
728 if (op->type == PLAYER) 805 if (op->type == PLAYER)
729 { 806 {
730 if (op->contr->last_used==tmp && op->contr->last_used_id == tmp->count) { 807 if (op->contr->last_used == tmp && op->contr->last_used_id == tmp->count)
808 {
731 object *n=NULL; 809 object *n = NULL;
810
732 if(tmp->below != NULL) 811 if (tmp->below != NULL)
733 n = tmp->below; 812 n = tmp->below;
734 else if(tmp->above != NULL) 813 else if (tmp->above != NULL)
735 n = tmp->above; 814 n = tmp->above;
736 op->contr->last_used = n; 815 op->contr->last_used = n;
737 if (n != NULL) 816 if (n != NULL)
738 op->contr->last_used_id = n->count; 817 op->contr->last_used_id = n->count;
818 else
819 op->contr->last_used_id = 0;
820 }
821 };
822
823 if (op->container)
824 {
825 if (op->type == PLAYER)
826 {
827 put_object_in_sack (op, op->container, tmp, op->contr->count);
828 }
739 else 829 else
740 op->contr->last_used_id = 0;
741 }
742 };
743
744 if (op->container) {
745 if (op->type == PLAYER)
746 { 830 {
747 put_object_in_sack (op, op->container, tmp, op->contr->count);
748 } else {
749 put_object_in_sack(op, op->container, tmp, 0); 831 put_object_in_sack (op, op->container, tmp, 0);
750 }; 832 };
751 } else { 833 }
834 else
835 {
752 if (op->type == PLAYER) 836 if (op->type == PLAYER)
753 { 837 {
754 drop_object (op, tmp, op->contr->count); 838 drop_object (op, tmp, op->contr->count);
839 }
755 } else { 840 else
841 {
756 drop_object(op,tmp,0); 842 drop_object (op, tmp, 0);
757 }; 843 };
758 } 844 }
759 if (op->type == PLAYER) 845 if (op->type == PLAYER)
760 op->contr->count = 0; 846 op->contr->count = 0;
761} 847}
762 848
763 849
764 850
765/* Command will drop all items that have not been locked */ 851/* Command will drop all items that have not been locked */
852int
766int command_dropall (object *op, char *params) { 853command_dropall (object *op, char *params)
854{
767 855
768 object * curinv, *nextinv; 856 object *curinv, *nextinv;
769 857
770 if(op->inv == NULL) { 858 if (op->inv == NULL)
859 {
771 new_draw_info(NDI_UNIQUE, 0,op,"Nothing to drop!"); 860 new_draw_info (NDI_UNIQUE, 0, op, "Nothing to drop!");
772 return 0; 861 return 0;
773 } 862 }
774 863
775 curinv = op->inv; 864 curinv = op->inv;
776 865
777 /* 866 /*
778 This is the default. Drops everything not locked or considered 867 This is the default. Drops everything not locked or considered
779 not something that should be dropped. 868 not something that should be dropped.
780 */ 869 */
781 /* 870 /*
782 Care must be taken that the next item pointer is not to money as 871 Care must be taken that the next item pointer is not to money as
783 the drop() routine will do unknown things to it when dropping 872 the drop() routine will do unknown things to it when dropping
784 in a shop. --Tero.Pelander@utu.fi 873 in a shop. --Tero.Pelander@utu.fi
785 */ 874 */
786 875
787 if(params==NULL) { 876 if (params == NULL)
877 {
788 while(curinv != NULL) { 878 while (curinv != NULL)
879 {
789 nextinv = curinv->below; 880 nextinv = curinv->below;
790 while (nextinv && nextinv->type==MONEY) 881 while (nextinv && nextinv->type == MONEY)
791 nextinv = nextinv->below; 882 nextinv = nextinv->below;
792 if(! QUERY_FLAG(curinv,FLAG_INV_LOCKED) && curinv->type != MONEY && 883 if (!QUERY_FLAG (curinv, FLAG_INV_LOCKED) && curinv->type != MONEY &&
793 curinv->type != FOOD && curinv->type != KEY && 884 curinv->type != FOOD && curinv->type != KEY &&
794 curinv->type != SPECIAL_KEY && curinv->type != GEM && 885 curinv->type != SPECIAL_KEY && curinv->type != GEM &&
795 !curinv->invisible &&
796 (curinv->type!=CONTAINER || op->container!=curinv)) 886 !curinv->invisible && (curinv->type != CONTAINER || op->container != curinv))
797 { 887 {
798 drop(op,curinv);
799 }
800 curinv = nextinv;
801 }
802 }
803
804 else if(strcmp(params, "weapons") == 0) {
805 while(curinv != NULL) {
806 nextinv = curinv->below;
807 while (nextinv && nextinv->type==MONEY)
808 nextinv = nextinv->below;
809 if(! QUERY_FLAG(curinv,FLAG_INV_LOCKED) && ((curinv->type == WEAPON) ||
810 (curinv->type == BOW) || (curinv->type == ARROW)))
811 {
812 drop(op,curinv); 888 drop (op, curinv);
813 } 889 }
814 curinv = nextinv;
815 }
816 }
817
818 else if(strcmp(params, "armor") == 0 || strcmp(params, "armour") == 0) {
819 while(curinv != NULL) {
820 nextinv = curinv->below;
821 while (nextinv && nextinv->type==MONEY)
822 nextinv = nextinv->below;
823 if(! QUERY_FLAG(curinv,FLAG_INV_LOCKED) && ((curinv->type == ARMOUR) ||
824 curinv->type == SHIELD || curinv->type==HELMET))
825 {
826 drop(op,curinv);
827 }
828 curinv = nextinv;
829 }
830 }
831
832 else if(strcmp(params, "misc") == 0) {
833 while(curinv != NULL) {
834 nextinv = curinv->below;
835 while (nextinv && nextinv->type==MONEY)
836 nextinv = nextinv->below;
837 if(! QUERY_FLAG(curinv,FLAG_INV_LOCKED) && ! QUERY_FLAG(curinv,FLAG_APPLIED)) {
838 switch(curinv->type) {
839 case HORN:
840 case BOOK:
841 case SPELLBOOK:
842 case GIRDLE:
843 case AMULET:
844 case RING:
845 case CLOAK:
846 case BOOTS:
847 case GLOVES:
848 case BRACERS:
849 case SCROLL:
850 case ARMOUR_IMPROVER:
851 case WEAPON_IMPROVER:
852 case WAND:
853 case ROD:
854 case POTION:
855 drop(op,curinv);
856 curinv = nextinv; 890 curinv = nextinv;
857 break; 891 }
858 default: 892 }
893
894 else if (strcmp (params, "weapons") == 0)
895 {
896 while (curinv != NULL)
897 {
898 nextinv = curinv->below;
899 while (nextinv && nextinv->type == MONEY)
900 nextinv = nextinv->below;
901 if (!QUERY_FLAG (curinv, FLAG_INV_LOCKED) && ((curinv->type == WEAPON) || (curinv->type == BOW) || (curinv->type == ARROW)))
902 {
903 drop (op, curinv);
904 }
859 curinv = nextinv; 905 curinv = nextinv;
860 break; 906 }
907 }
908
909 else if (strcmp (params, "armor") == 0 || strcmp (params, "armour") == 0)
910 {
911 while (curinv != NULL)
861 } 912 {
862 } 913 nextinv = curinv->below;
914 while (nextinv && nextinv->type == MONEY)
915 nextinv = nextinv->below;
916 if (!QUERY_FLAG (curinv, FLAG_INV_LOCKED) && ((curinv->type == ARMOUR) || curinv->type == SHIELD || curinv->type == HELMET))
917 {
918 drop (op, curinv);
919 }
863 curinv = nextinv; 920 curinv = nextinv;
921 }
922 }
923
924 else if (strcmp (params, "misc") == 0)
864 } 925 {
926 while (curinv != NULL)
927 {
928 nextinv = curinv->below;
929 while (nextinv && nextinv->type == MONEY)
930 nextinv = nextinv->below;
931 if (!QUERY_FLAG (curinv, FLAG_INV_LOCKED) && !QUERY_FLAG (curinv, FLAG_APPLIED))
932 {
933 switch (curinv->type)
934 {
935 case HORN:
936 case BOOK:
937 case SPELLBOOK:
938 case GIRDLE:
939 case AMULET:
940 case RING:
941 case CLOAK:
942 case BOOTS:
943 case GLOVES:
944 case BRACERS:
945 case SCROLL:
946 case ARMOUR_IMPROVER:
947 case WEAPON_IMPROVER:
948 case WAND:
949 case ROD:
950 case POTION:
951 drop (op, curinv);
952 curinv = nextinv;
953 break;
954 default:
955 curinv = nextinv;
956 break;
957 }
958 }
959 curinv = nextinv;
960 }
865 } 961 }
866 op->contr->socket.update_look=1; 962 op->contr->socket.update_look = 1;
963
867/* draw_look(op);*/ 964/* draw_look(op);*/
868 return 0; 965 return 0;
869} 966}
870 967
871/* Object op wants to drop object(s) params. params can be a 968/* Object op wants to drop object(s) params. params can be a
872 * comma seperated list. 969 * comma seperated list.
873 */ 970 */
874 971
972int
875int command_drop (object *op, char *params) 973command_drop (object *op, char *params)
876{ 974{
877 object *tmp, *next; 975 object *tmp, *next;
878 int did_one=0; 976 int did_one = 0;
879 977
880 if (!params) { 978 if (!params)
979 {
881 new_draw_info(NDI_UNIQUE,0, op, "Drop what?"); 980 new_draw_info (NDI_UNIQUE, 0, op, "Drop what?");
882 return 0; 981 return 0;
883 } else { 982 }
983 else
984 {
884 for (tmp=op->inv; tmp; tmp=next) { 985 for (tmp = op->inv; tmp; tmp = next)
986 {
885 next=tmp->below; 987 next = tmp->below;
886 if (QUERY_FLAG(tmp,FLAG_NO_DROP) || 988 if (QUERY_FLAG (tmp, FLAG_NO_DROP) || tmp->invisible)
887 tmp->invisible) continue; 989 continue;
888 if (item_matched_string(op,tmp,params)) { 990 if (item_matched_string (op, tmp, params))
991 {
889 drop(op, tmp); 992 drop (op, tmp);
890 did_one=1; 993 did_one = 1;
891 } 994 }
892 } 995 }
996 if (!did_one)
893 if (!did_one) new_draw_info(NDI_UNIQUE, 0,op,"Nothing to drop."); 997 new_draw_info (NDI_UNIQUE, 0, op, "Nothing to drop.");
894 } 998 }
895 if (op->type==PLAYER) 999 if (op->type == PLAYER)
896 { 1000 {
897 op->contr->count=0; 1001 op->contr->count = 0;
898 op->contr->socket.update_look=1; 1002 op->contr->socket.update_look = 1;
899 }; 1003 };
1004
900/* draw_look(op);*/ 1005/* draw_look(op);*/
901 return 0; 1006 return 0;
902} 1007}
903 1008
1009int
904int command_examine (object *op, char *params) 1010command_examine (object *op, char *params)
905{ 1011{
906 if (!params) { 1012 if (!params)
1013 {
907 object *tmp=op->below; 1014 object *tmp = op->below;
1015
908 while (tmp && !LOOK_OBJ(tmp)) tmp=tmp->below; 1016 while (tmp && !LOOK_OBJ (tmp))
909 if (tmp) examine(op,tmp); 1017 tmp = tmp->below;
910 }
911 else {
912 object *tmp=find_best_object_match(op,params);
913 if (tmp) 1018 if (tmp)
914 examine(op,tmp); 1019 examine (op, tmp);
1020 }
1021 else
1022 {
1023 object *tmp = find_best_object_match (op, params);
1024
1025 if (tmp)
1026 examine (op, tmp);
915 else 1027 else
916 new_draw_info_format(NDI_UNIQUE,0,op,"Could not find an object that matches %s",params); 1028 new_draw_info_format (NDI_UNIQUE, 0, op, "Could not find an object that matches %s", params);
917 } 1029 }
918 return 0; 1030 return 0;
919} 1031}
920 1032
921/* op should be a player. 1033/* op should be a player.
922 * we return the object the player has marked with the 'mark' command 1034 * we return the object the player has marked with the 'mark' command
923 * below. If no match is found (or object has changed), we return 1035 * below. If no match is found (or object has changed), we return
924 * NULL. We leave it up to the calling function to print messages if 1036 * NULL. We leave it up to the calling function to print messages if
925 * nothing is found. 1037 * nothing is found.
926 */ 1038 */
1039object *
927object *find_marked_object(object *op) 1040find_marked_object (object *op)
928{ 1041{
929 object *tmp; 1042 object *tmp;
930 1043
931 if (!op || !op->contr) return NULL; 1044 if (!op || !op->contr)
1045 return NULL;
1046
932 if (!op->contr->mark) { 1047 if (!op->contr->mark)
1048 {
933/* new_draw_info(NDI_UNIQUE,0,op,"You have no marked object");*/ 1049/* new_draw_info(NDI_UNIQUE,0,op,"You have no marked object");*/
934 return NULL; 1050 return 0;
935 } 1051 }
1052
936 /* This may seem like overkill, but we need to make sure that they 1053 /* This may seem like overkill, but we need to make sure that they
937 * player hasn't dropped the item. We use count on the off chance that 1054 * player hasn't dropped the item. We use count on the off chance that
938 * an item got reincarnated at some point. 1055 * an item got reincarnated at some point.
939 */ 1056 */
940 for (tmp=op->inv; tmp; tmp=tmp->below) { 1057 for (tmp = op->inv; tmp; tmp = tmp->below)
1058 {
941 if (tmp->invisible) continue; 1059 if (tmp->invisible)
1060 continue;
1061
942 if (tmp == op->contr->mark) { 1062 if (tmp == op->contr->mark)
943 if (tmp->count == op->contr->mark_count) 1063 {
1064 if (!tmp->destroyed ())
944 return tmp; 1065 return tmp;
945 else { 1066 else
1067 {
946 op->contr->mark=NULL; 1068 op->contr->mark = 0;
947 op->contr->mark_count=0;
948/* new_draw_info(NDI_UNIQUE,0,op,"You have no marked object");*/ 1069/* new_draw_info(NDI_UNIQUE,0,op,"You have no marked object");*/
949 return NULL; 1070 return 0;
950 } 1071 }
951 } 1072 }
952 } 1073 }
953 return NULL; 1074
1075 return 0;
954} 1076}
955 1077
956 1078
957/* op should be a player, params is any params. 1079/* op should be a player, params is any params.
958 * If no params given, we print out the currently marked object. 1080 * If no params given, we print out the currently marked object.
959 * otherwise, try to find a matching object - try best match first. 1081 * otherwise, try to find a matching object - try best match first.
960 */ 1082 */
1083int
961int command_mark(object *op, char *params) 1084command_mark (object *op, char *params)
962{ 1085{
963 if (!op->contr) return 1; 1086 if (!op->contr)
1087 return 1;
1088
964 if (!params) { 1089 if (!params)
1090 {
965 object *mark=find_marked_object(op); 1091 object *mark = find_marked_object (op);
1092
1093 if (!mark)
966 if (!mark) new_draw_info(NDI_UNIQUE,0,op,"You have no marked object."); 1094 new_draw_info (NDI_UNIQUE, 0, op, "You have no marked object.");
1095 else
967 else new_draw_info_format(NDI_UNIQUE,0,op,"%s is marked.", query_name(mark)); 1096 new_draw_info_format (NDI_UNIQUE, 0, op, "%s is marked.", query_name (mark));
1097 }
1098 else
968 } 1099 {
969 else {
970 object *mark1=find_best_object_match(op, params); 1100 object *mark1 = find_best_object_match (op, params);
1101
971 if (!mark1) { 1102 if (!mark1)
1103 {
972 new_draw_info_format(NDI_UNIQUE,0,op,"Could not find an object that matches %s",params); 1104 new_draw_info_format (NDI_UNIQUE, 0, op, "Could not find an object that matches %s", params);
973 return 1; 1105 return 1;
1106 }
1107 else
974 } 1108 {
975 else {
976 op->contr->mark=mark1; 1109 op->contr->mark = mark1;
977 op->contr->mark_count=mark1->count;
978 new_draw_info_format(NDI_UNIQUE,0,op,"Marked item %s", query_name(mark1)); 1110 new_draw_info_format (NDI_UNIQUE, 0, op, "Marked item %s", query_name (mark1));
979 return 0; 1111 return 0;
980 } 1112 }
981 } 1113 }
982 return 0; /*shouldnt get here */ 1114
1115 return 0; /*shouldnt get here */
983} 1116}
984 1117
985 1118
986/* op is the player 1119/* op is the player
987 * tmp is the monster being examined. 1120 * tmp is the monster being examined.
988 */ 1121 */
1122void
989void examine_monster(object *op,object *tmp) { 1123examine_monster (object *op, object *tmp)
1124{
990 object *mon=tmp->head?tmp->head:tmp; 1125 object *mon = tmp->head ? tmp->head : tmp;
991 1126
992 if(QUERY_FLAG(mon,FLAG_UNDEAD)) 1127 if (QUERY_FLAG (mon, FLAG_UNDEAD))
993 new_draw_info(NDI_UNIQUE, 0,op,"It is an undead force."); 1128 new_draw_info (NDI_UNIQUE, 0, op, "It is an undead force.");
994 if(mon->level>op->level) 1129 if (mon->level > op->level)
995 new_draw_info(NDI_UNIQUE, 0,op,"It is likely more powerful than you."); 1130 new_draw_info (NDI_UNIQUE, 0, op, "It is likely more powerful than you.");
996 else if(mon->level<op->level) 1131 else if (mon->level < op->level)
997 new_draw_info(NDI_UNIQUE, 0,op,"It is likely less powerful than you."); 1132 new_draw_info (NDI_UNIQUE, 0, op, "It is likely less powerful than you.");
998 else 1133 else
999 new_draw_info(NDI_UNIQUE, 0,op,"It is probably as powerful as you."); 1134 new_draw_info (NDI_UNIQUE, 0, op, "It is probably as powerful as you.");
1000 if(mon->attacktype&AT_ACID) 1135 if (mon->attacktype & AT_ACID)
1001 new_draw_info(NDI_UNIQUE, 0,op,"You seem to smell an acrid odor."); 1136 new_draw_info (NDI_UNIQUE, 0, op, "You seem to smell an acrid odor.");
1002 1137
1003 /* Anyone know why this used to use the clone value instead of the 1138 /* Anyone know why this used to use the clone value instead of the
1004 * maxhp field? This seems that it should give more accurate results. 1139 * maxhp field? This seems that it should give more accurate results.
1005 */ 1140 */
1006 switch((mon->stats.hp+1)*4/(mon->stats.maxhp+1)) { /* From 1-4 */ 1141 switch ((mon->stats.hp + 1) * 4 / (mon->stats.maxhp + 1))
1142 { /* From 1-4 */
1007 case 1: 1143 case 1:
1008 new_draw_info(NDI_UNIQUE, 0,op,"It is in a bad shape."); 1144 new_draw_info (NDI_UNIQUE, 0, op, "It is in a bad shape.");
1009 break; 1145 break;
1010 case 2: 1146 case 2:
1011 new_draw_info(NDI_UNIQUE, 0,op,"It is hurt."); 1147 new_draw_info (NDI_UNIQUE, 0, op, "It is hurt.");
1012 break; 1148 break;
1013 case 3: 1149 case 3:
1014 new_draw_info(NDI_UNIQUE, 0,op,"It is somewhat hurt."); 1150 new_draw_info (NDI_UNIQUE, 0, op, "It is somewhat hurt.");
1015 break; 1151 break;
1016 case 4: 1152 case 4:
1017 new_draw_info(NDI_UNIQUE, 0,op,"It is in excellent shape."); 1153 new_draw_info (NDI_UNIQUE, 0, op, "It is in excellent shape.");
1018 break; 1154 break;
1019 } 1155 }
1020 if(present_in_ob(POISONING,mon)!=NULL) 1156 if (present_in_ob (POISONING, mon) != NULL)
1021 new_draw_info(NDI_UNIQUE, 0,op,"It looks very ill."); 1157 new_draw_info (NDI_UNIQUE, 0, op, "It looks very ill.");
1022} 1158}
1023 1159
1024 1160
1025/* tmp is the object being described, pl is who is examing it. */ 1161/* tmp is the object being described, pl is who is examing it. */
1162char *
1026char *long_desc(object *tmp, object *pl) { 1163long_desc (object *tmp, object *pl)
1164{
1027 static char buf[VERY_BIG_BUF]; 1165 static char buf[VERY_BIG_BUF];
1028 char *cp; 1166 char *cp;
1029 1167
1030 if(tmp==NULL) 1168 if (tmp == NULL)
1031 return ""; 1169 return "";
1032 1170
1033 buf[0]='\0'; 1171 buf[0] = '\0';
1034 switch(tmp->type) { 1172 switch (tmp->type)
1173 {
1035 case RING: 1174 case RING:
1036 case SKILL: 1175 case SKILL:
1037 case WEAPON: 1176 case WEAPON:
1038 case ARMOUR: 1177 case ARMOUR:
1039 case BRACERS: 1178 case BRACERS:
1040 case HELMET: 1179 case HELMET:
1041 case SHIELD: 1180 case SHIELD:
1042 case BOOTS: 1181 case BOOTS:
1043 case GLOVES: 1182 case GLOVES:
1044 case AMULET: 1183 case AMULET:
1045 case GIRDLE: 1184 case GIRDLE:
1046 case BOW: 1185 case BOW:
1047 case ARROW: 1186 case ARROW:
1048 case CLOAK: 1187 case CLOAK:
1049 case FOOD: 1188 case FOOD:
1050 case DRINK: 1189 case DRINK:
1051 case FLESH: 1190 case FLESH:
1052 case SKILL_TOOL: 1191 case SKILL_TOOL:
1053 case POWER_CRYSTAL: 1192 case POWER_CRYSTAL:
1054 if(*(cp=describe_item(tmp, pl))!='\0') { 1193 if (*(cp = describe_item (tmp, pl)) != '\0')
1194 {
1055 int len; 1195 int len;
1056 1196
1057 strncpy(buf,query_name(tmp), VERY_BIG_BUF-1); 1197 assign (buf, query_name (tmp));
1058 buf[VERY_BIG_BUF-1]=0;
1059 len=strlen(buf); 1198 len = strlen (buf);
1060 if (len<VERY_BIG_BUF-5) { 1199 if (len < VERY_BIG_BUF - 5)
1200 {
1061 /* Since we know the length, we save a few cpu cycles by using 1201 /* Since we know the length, we save a few cpu cycles by using
1062 * it instead of calling strcat */ 1202 * it instead of calling strcat */
1063 strcpy(buf+len," "); 1203 strcpy (buf + len, " ");
1064 len++; 1204 len++;
1065 strncpy(buf+len, cp, VERY_BIG_BUF-len-1); 1205 assign (buf + len, cp, VERY_BIG_BUF - len - 1);
1066 buf[VERY_BIG_BUF-1]=0;
1067 } 1206 }
1068 } 1207 }
1069 } 1208 }
1209
1070 if(buf[0]=='\0') { 1210 if (buf[0] == '\0')
1071 strncpy(buf,query_name(tmp), VERY_BIG_BUF-1); 1211 assign (buf, query_name (tmp));
1072 buf[VERY_BIG_BUF-1]=0;
1073 }
1074 1212
1075 return buf; 1213 return buf;
1076} 1214}
1077 1215
1216void
1078void examine(object *op, object *tmp) { 1217examine (object *op, object *tmp)
1218{
1079 char buf[VERY_BIG_BUF]; 1219 char buf[VERY_BIG_BUF];
1080 int i; 1220 int i;
1081 1221
1082 if (tmp == NULL || tmp->type == CLOSE_CON) 1222 if (tmp == NULL || tmp->type == CLOSE_CON)
1083 return; 1223 return;
1084 1224
1085 strcpy(buf,"That is "); 1225 strcpy (buf, "That is ");
1086 strncat(buf, long_desc(tmp, op), VERY_BIG_BUF-strlen(buf)-1); 1226 strncat (buf, long_desc (tmp, op), VERY_BIG_BUF - strlen (buf) - 1);
1087 buf[VERY_BIG_BUF-1]=0; 1227 buf[VERY_BIG_BUF - 1] = 0;
1088 1228
1089 new_draw_info(NDI_UNIQUE, 0,op,buf); 1229 new_draw_info (NDI_UNIQUE, 0, op, buf);
1090 buf[0]='\0'; 1230 buf[0] = '\0';
1091 1231
1092 if(tmp->custom_name) { 1232 if (tmp->custom_name)
1233 {
1093 strcpy(buf,"You call it "); 1234 strcpy (buf, "You call it ");
1094 strncat(buf, tmp->custom_name, VERY_BIG_BUF-strlen(buf)-1); 1235 strncat (buf, tmp->custom_name, VERY_BIG_BUF - strlen (buf) - 1);
1095 buf[VERY_BIG_BUF-1]=0; 1236 buf[VERY_BIG_BUF - 1] = 0;
1096 new_draw_info(NDI_UNIQUE, 0,op,buf); 1237 new_draw_info (NDI_UNIQUE, 0, op, buf);
1097 buf[0]='\0'; 1238 buf[0] = '\0';
1098 } 1239 }
1099 1240
1100 switch(tmp->type) { 1241 switch (tmp->type)
1242 {
1101 case SPELLBOOK: 1243 case SPELLBOOK:
1102 if(QUERY_FLAG(tmp, FLAG_IDENTIFIED) && tmp->inv ) { 1244 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) && tmp->inv)
1103 sprintf(buf,"%s is a %s level %s spell", 1245 {
1104 tmp->inv->name, get_levelnumber(tmp->inv->level), 1246 sprintf (buf, "%s is a %s level %s spell", &tmp->inv->name, get_levelnumber (tmp->inv->level), &tmp->inv->skill);
1105 tmp->inv->skill);
1106 } 1247 }
1107 break; 1248 break;
1108 1249
1109 case BOOK: 1250 case BOOK:
1110 if(tmp->msg!=NULL) 1251 if (tmp->msg != NULL)
1111 strcpy(buf,"Something is written in it."); 1252 strcpy (buf, "Something is written in it.");
1112 break; 1253 break;
1113 1254
1114 case CONTAINER: 1255 case CONTAINER:
1115 if(tmp->race!=NULL) { 1256 if (tmp->race != NULL)
1257 {
1116 if(tmp->weight_limit && tmp->stats.Str<100) 1258 if (tmp->weight_limit && tmp->stats.Str < 100)
1117 sprintf (buf,"It can hold only %s and its weight limit is %.1f kg.", 1259 sprintf (buf, "It can hold only %s and its weight limit is %.1f kg.",
1118 tmp->race, tmp->weight_limit/(10.0 * (100 - tmp->stats.Str))); 1260 &tmp->race, tmp->weight_limit / (10.0 * (100 - tmp->stats.Str)));
1119 else
1120 sprintf (buf,"It can hold only %s.", tmp->race);
1121 } else
1122 if(tmp->weight_limit && tmp->stats.Str<100)
1123 sprintf (buf,"Its weight limit is %.1f kg.",
1124 tmp->weight_limit/(10.0 * (100 - tmp->stats.Str)));
1125 break;
1126
1127 case WAND:
1128 if(QUERY_FLAG(tmp, FLAG_IDENTIFIED))
1129 sprintf(buf,"It has %d charges left.",tmp->stats.food);
1130 break;
1131 }
1132
1133 if(buf[0]!='\0')
1134 new_draw_info(NDI_UNIQUE, 0,op,buf);
1135
1136 if(tmp->materialname != NULL && !tmp->msg) {
1137 sprintf(buf, "It is made of: %s.", tmp->materialname);
1138 new_draw_info(NDI_UNIQUE, 0, op, buf);
1139 }
1140 /* Where to wear this item */
1141 for (i=0; i < NUM_BODY_LOCATIONS; i++) {
1142 if (tmp->body_info[i]<-1) {
1143 if (op->body_info[i])
1144 new_draw_info_format(NDI_UNIQUE, 0,op,
1145 "It goes %s (%d)", body_locations[i].use_name, -tmp->body_info[i]);
1146 else 1261 else
1262 sprintf (buf, "It can hold only %s.", &tmp->race);
1263 }
1264 else if (tmp->weight_limit && tmp->stats.Str < 100)
1265 sprintf (buf, "Its weight limit is %.1f kg.", tmp->weight_limit / (10.0 * (100 - tmp->stats.Str)));
1266 break;
1267
1268 case WAND:
1269 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1270 sprintf (buf, "It has %d charges left.", tmp->stats.food);
1271 break;
1272 }
1273
1274 if (buf[0] != '\0')
1275 new_draw_info (NDI_UNIQUE, 0, op, buf);
1276
1277 if (tmp->materialname != NULL && !tmp->msg)
1278 {
1279 sprintf (buf, "It is made of: %s.", &tmp->materialname);
1147 new_draw_info_format(NDI_UNIQUE, 0,op, 1280 new_draw_info (NDI_UNIQUE, 0, op, buf);
1148 "It goes %s", body_locations[i].nonuse_name); 1281 }
1282 /* Where to wear this item */
1283 for (i = 0; i < NUM_BODY_LOCATIONS; i++)
1284 {
1149 } else if (tmp->body_info[i]) { 1285 if (tmp->body_info[i] < -1)
1286 {
1150 if (op->body_info[i]) 1287 if (op->body_info[i])
1151 new_draw_info_format(NDI_UNIQUE, 0,op, 1288 new_draw_info_format (NDI_UNIQUE, 0, op, "It goes %s (%d)", body_locations[i].use_name, -tmp->body_info[i]);
1152 "It goes %s", body_locations[i].use_name);
1153 else 1289 else
1154 new_draw_info_format(NDI_UNIQUE, 0,op, 1290 new_draw_info_format (NDI_UNIQUE, 0, op, "It goes %s", body_locations[i].nonuse_name);
1155 "It goes %s", body_locations[i].nonuse_name); 1291 }
1292 else if (tmp->body_info[i])
1156 } 1293 {
1294 if (op->body_info[i])
1295 new_draw_info_format (NDI_UNIQUE, 0, op, "It goes %s", body_locations[i].use_name);
1296 else
1297 new_draw_info_format (NDI_UNIQUE, 0, op, "It goes %s", body_locations[i].nonuse_name);
1298 }
1157 } 1299 }
1158 1300
1159 if(tmp->weight) { 1301 if (tmp->weight)
1160 sprintf(buf,tmp->nrof>1?"They weigh %3.3f kg.":"It weighs %3.3f kg.", 1302 {
1161 tmp->weight*(tmp->nrof?tmp->nrof:1)/1000.0); 1303 sprintf (buf, tmp->nrof > 1 ? "They weigh %3.3f kg." : "It weighs %3.3f kg.", tmp->weight * (tmp->nrof ? tmp->nrof : 1) / 1000.0);
1162 new_draw_info(NDI_UNIQUE, 0,op,buf); 1304 new_draw_info (NDI_UNIQUE, 0, op, buf);
1163 } 1305 }
1164 1306
1165 if (tmp->value && !QUERY_FLAG(tmp, FLAG_STARTEQUIP) && !QUERY_FLAG(tmp, FLAG_NO_PICK)) { 1307 if (tmp->value && !QUERY_FLAG (tmp, FLAG_STARTEQUIP) && !QUERY_FLAG (tmp, FLAG_NO_PICK))
1166 sprintf(buf,"You reckon %s worth %s.", 1308 {
1167 tmp->nrof>1?"they are":"it is",query_cost_string(tmp,op, F_TRUE | F_APPROX)); 1309 sprintf (buf, "You reckon %s worth %s.", tmp->nrof > 1 ? "they are" : "it is", query_cost_string (tmp, op, F_TRUE | F_APPROX));
1168 new_draw_info(NDI_UNIQUE, 0,op,buf); 1310 new_draw_info (NDI_UNIQUE, 0, op, buf);
1169 if (is_in_shop (op)) { 1311 if (is_in_shop (op))
1312 {
1170 if(QUERY_FLAG(tmp, FLAG_UNPAID)) 1313 if (QUERY_FLAG (tmp, FLAG_UNPAID))
1171 sprintf(buf,"%s would cost you %s.", 1314 sprintf (buf, "%s would cost you %s.", tmp->nrof > 1 ? "They" : "It", query_cost_string (tmp, op, F_BUY | F_SHOP));
1172 tmp->nrof>1?"They":"It",query_cost_string(tmp,op,F_BUY | F_SHOP));
1173 else 1315 else
1174 sprintf(buf,"You are offered %s for %s.", 1316 sprintf (buf, "You are offered %s for %s.", query_cost_string (tmp, op, F_SELL + F_SHOP), tmp->nrof > 1 ? "them" : "it");
1175 query_cost_string(tmp,op,F_SELL+F_SHOP), tmp->nrof>1?"them":"it");
1176 new_draw_info(NDI_UNIQUE, 0,op,buf); 1317 new_draw_info (NDI_UNIQUE, 0, op, buf);
1177 } 1318 }
1178 } 1319 }
1179 1320
1180 if(QUERY_FLAG(tmp, FLAG_MONSTER)) 1321 if (QUERY_FLAG (tmp, FLAG_MONSTER))
1181 examine_monster(op,tmp); 1322 examine_monster (op, tmp);
1182 1323
1183 /* Is this item buildable? */ 1324 /* Is this item buildable? */
1184 if ( QUERY_FLAG( tmp, FLAG_IS_BUILDABLE ) ) 1325 if (QUERY_FLAG (tmp, FLAG_IS_BUILDABLE))
1185 new_draw_info( NDI_UNIQUE, 0, op, "This is a buildable item." ); 1326 new_draw_info (NDI_UNIQUE, 0, op, "This is a buildable item.");
1186 1327
1187 /* Does the object have a message? Don't show message for all object 1328 /* Does the object have a message? Don't show message for all object
1188 * types - especially if the first entry is a match 1329 * types - especially if the first entry is a match
1189 */ 1330 */
1190 if(tmp->msg && tmp->type != EXIT && tmp->type != BOOK && 1331 if (tmp->msg && tmp->type != EXIT && tmp->type != BOOK && tmp->type != CORPSE && !tmp->move_on && strncasecmp (tmp->msg, "@match", 7))
1191 tmp->type != CORPSE && !tmp->move_on && 1332 {
1192 strncasecmp(tmp->msg, "@match",7)) {
1193 1333
1194 /* This is just a hack so when identifying the items, we print 1334 /* This is just a hack so when identifying the items, we print
1195 * out the extra message 1335 * out the extra message
1196 */ 1336 */
1197 if (need_identify(tmp) && QUERY_FLAG(tmp, FLAG_IDENTIFIED)) 1337 if (need_identify (tmp) && QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1198 new_draw_info(NDI_UNIQUE, 0,op, "The object has a story:"); 1338 new_draw_info (NDI_UNIQUE, 0, op, "The object has a story:");
1199 1339
1200 new_draw_info(NDI_UNIQUE, 0,op,tmp->msg); 1340 new_draw_info (NDI_UNIQUE, 0, op, tmp->msg);
1201 } 1341 }
1202 new_draw_info(NDI_UNIQUE, 0,op," "); /* Blank line */ 1342 new_draw_info (NDI_UNIQUE, 0, op, " "); /* Blank line */
1203} 1343}
1204 1344
1205/* 1345/*
1206 * inventory prints object's inventory. If inv==NULL then print player's 1346 * inventory prints object's inventory. If inv==NULL then print player's
1207 * inventory. 1347 * inventory.
1208 * [ Only items which are applied are showed. Tero.Haatanen@lut.fi ] 1348 * [ Only items which are applied are showed. Tero.Haatanen@lut.fi ]
1209 */ 1349 */
1350void
1210void inventory(object *op,object *inv) { 1351inventory (object *op, object *inv)
1352{
1211 object *tmp; 1353 object *tmp;
1212 char *in; 1354 char *in;
1213 int items = 0, length; 1355 int items = 0, length;
1214 1356
1215 if (inv==NULL && op==NULL) { 1357 if (inv == NULL && op == NULL)
1358 {
1216 new_draw_info(NDI_UNIQUE, 0,op,"Inventory of what object?"); 1359 new_draw_info (NDI_UNIQUE, 0, op, "Inventory of what object?");
1360 return;
1361 }
1362 tmp = inv ? inv->inv : op->inv;
1363
1364 while (tmp)
1365 {
1366 if ((!tmp->invisible &&
1367 (inv == NULL || inv->type == CONTAINER || QUERY_FLAG (tmp, FLAG_APPLIED))) || (!op || QUERY_FLAG (op, FLAG_WIZ)))
1368 items++;
1369 tmp = tmp->below;
1370 }
1371 if (inv == NULL)
1372 { /* player's inventory */
1373 if (items == 0)
1374 {
1375 new_draw_info (NDI_UNIQUE, 0, op, "You carry nothing.");
1376 return;
1377 }
1378 else
1379 {
1380 length = 28;
1381 in = "";
1382 if (op)
1383 clear_win_info (op);
1384 new_draw_info (NDI_UNIQUE, 0, op, "Inventory:");
1385 }
1386 }
1387 else
1388 {
1389 if (items == 0)
1390 return;
1391 else
1392 {
1393 length = 28;
1394 in = " ";
1395 }
1396 }
1397 for (tmp = inv ? inv->inv : op->inv; tmp; tmp = tmp->below)
1398 {
1399 if ((!op || !QUERY_FLAG (op, FLAG_WIZ)) && (tmp->invisible || (inv && inv->type != CONTAINER && !QUERY_FLAG (tmp, FLAG_APPLIED))))
1400 continue;
1401 if ((!op || QUERY_FLAG (op, FLAG_WIZ)))
1402 new_draw_info_format (NDI_UNIQUE, 0, op, "%s- %-*.*s (%5d) %-8s", in, length, length,
1403 query_name (tmp), tmp->count, query_weight (tmp));
1404 else
1405 new_draw_info_format (NDI_UNIQUE, 0, op, "%s- %-*.*s %-8s", in, length + 8, length + 8, query_name (tmp), query_weight (tmp));
1406 }
1407 if (!inv && op)
1408 {
1409 new_draw_info_format (NDI_UNIQUE, 0, op, "%-*s %-8s", 41, "Total weight :", query_weight (op));
1410 }
1411}
1412
1413static void
1414display_new_pickup (object *op)
1415{
1416 int i = op->contr->mode;
1417
1418 if (!(i & PU_NEWMODE))
1217 return; 1419 return;
1218 }
1219 tmp = inv ? inv->inv : op->inv;
1220 1420
1221 while (tmp) {
1222 if ((!tmp->invisible &&
1223 (inv==NULL || inv->type == CONTAINER || QUERY_FLAG(tmp, FLAG_APPLIED)))
1224 || (!op || QUERY_FLAG(op, FLAG_WIZ)))
1225 items++;
1226 tmp=tmp->below;
1227 }
1228 if (inv==NULL) { /* player's inventory */
1229 if (items==0) {
1230 new_draw_info(NDI_UNIQUE, 0,op,"You carry nothing.");
1231 return;
1232 } else {
1233 length = 28;
1234 in = "";
1235 if (op)
1236 clear_win_info(op);
1237 new_draw_info(NDI_UNIQUE, 0,op,"Inventory:");
1238 }
1239 } else {
1240 if (items==0)
1241 return;
1242 else {
1243 length = 28;
1244 in = " ";
1245 }
1246 }
1247 for (tmp=inv?inv->inv:op->inv; tmp; tmp=tmp->below) {
1248 if((!op||!QUERY_FLAG(op, FLAG_WIZ)) && (tmp->invisible ||
1249 (inv && inv->type != CONTAINER && !QUERY_FLAG(tmp, FLAG_APPLIED))))
1250 continue;
1251 if((!op || QUERY_FLAG(op, FLAG_WIZ)))
1252 new_draw_info_format(NDI_UNIQUE, 0,op ,"%s- %-*.*s (%5d) %-8s", in, length, length,
1253 query_name(tmp), tmp->count,query_weight(tmp));
1254 else
1255 new_draw_info_format(NDI_UNIQUE,0, op, "%s- %-*.*s %-8s", in, length+8,
1256 length+8, query_name(tmp),
1257 query_weight(tmp));
1258 }
1259 if(!inv && op) {
1260 new_draw_info_format(NDI_UNIQUE,0, op ,"%-*s %-8s",
1261 41,"Total weight :",query_weight(op));
1262 }
1263}
1264
1265static void display_new_pickup( object* op )
1266 {
1267 int i = op->contr->mode;
1268
1269 if(!(i & PU_NEWMODE)) return;
1270
1271 new_draw_info_format(NDI_UNIQUE, 0,op,"%d NEWMODE",i & PU_NEWMODE?1:0); 1421 new_draw_info_format (NDI_UNIQUE, 0, op, "%d NEWMODE", i & PU_NEWMODE ? 1 : 0);
1272 new_draw_info_format(NDI_UNIQUE, 0,op,"%d DEBUG",i & PU_DEBUG?1:0); 1422 new_draw_info_format (NDI_UNIQUE, 0, op, "%d DEBUG", i & PU_DEBUG ? 1 : 0);
1273 new_draw_info_format(NDI_UNIQUE, 0,op,"%d INHIBIT",i & PU_INHIBIT?1:0); 1423 new_draw_info_format (NDI_UNIQUE, 0, op, "%d INHIBIT", i & PU_INHIBIT ? 1 : 0);
1274 new_draw_info_format(NDI_UNIQUE, 0,op,"%d STOP",i & PU_STOP?1:0); 1424 new_draw_info_format (NDI_UNIQUE, 0, op, "%d STOP", i & PU_STOP ? 1 : 0);
1275 1425
1276 new_draw_info_format(NDI_UNIQUE, 0,op,"%d <= x pickup weight/value RATIO (0==off)",(i & PU_RATIO)*5); 1426 new_draw_info_format (NDI_UNIQUE, 0, op, "%d <= x pickup weight/value RATIO (0==off)", (i & PU_RATIO) * 5);
1277 1427
1278 new_draw_info_format(NDI_UNIQUE, 0,op,"%d FOOD",i & PU_FOOD?1:0); 1428 new_draw_info_format (NDI_UNIQUE, 0, op, "%d FOOD", i & PU_FOOD ? 1 : 0);
1279 new_draw_info_format(NDI_UNIQUE, 0,op,"%d DRINK",i & PU_DRINK?1:0); 1429 new_draw_info_format (NDI_UNIQUE, 0, op, "%d DRINK", i & PU_DRINK ? 1 : 0);
1280 new_draw_info_format(NDI_UNIQUE, 0,op,"%d VALUABLES",i & PU_VALUABLES?1:0); 1430 new_draw_info_format (NDI_UNIQUE, 0, op, "%d VALUABLES", i & PU_VALUABLES ? 1 : 0);
1281 1431
1282 new_draw_info_format(NDI_UNIQUE, 0,op,"%d BOW",i & PU_BOW?1:0); 1432 new_draw_info_format (NDI_UNIQUE, 0, op, "%d BOW", i & PU_BOW ? 1 : 0);
1283 new_draw_info_format(NDI_UNIQUE, 0,op,"%d ARROW",i & PU_ARROW?1:0); 1433 new_draw_info_format (NDI_UNIQUE, 0, op, "%d ARROW", i & PU_ARROW ? 1 : 0);
1284 1434
1285 new_draw_info_format(NDI_UNIQUE, 0,op,"%d HELMET",i & PU_HELMET?1:0); 1435 new_draw_info_format (NDI_UNIQUE, 0, op, "%d HELMET", i & PU_HELMET ? 1 : 0);
1286 new_draw_info_format(NDI_UNIQUE, 0,op,"%d SHIELD",i & PU_SHIELD?1:0); 1436 new_draw_info_format (NDI_UNIQUE, 0, op, "%d SHIELD", i & PU_SHIELD ? 1 : 0);
1287 new_draw_info_format(NDI_UNIQUE, 0,op,"%d ARMOUR",i & PU_ARMOUR?1:0); 1437 new_draw_info_format (NDI_UNIQUE, 0, op, "%d ARMOUR", i & PU_ARMOUR ? 1 : 0);
1288 1438
1289 new_draw_info_format(NDI_UNIQUE, 0,op,"%d BOOTS",i & PU_BOOTS?1:0); 1439 new_draw_info_format (NDI_UNIQUE, 0, op, "%d BOOTS", i & PU_BOOTS ? 1 : 0);
1290 new_draw_info_format(NDI_UNIQUE, 0,op,"%d GLOVES",i & PU_GLOVES?1:0); 1440 new_draw_info_format (NDI_UNIQUE, 0, op, "%d GLOVES", i & PU_GLOVES ? 1 : 0);
1291 new_draw_info_format(NDI_UNIQUE, 0,op,"%d CLOAK",i & PU_CLOAK?1:0); 1441 new_draw_info_format (NDI_UNIQUE, 0, op, "%d CLOAK", i & PU_CLOAK ? 1 : 0);
1292 new_draw_info_format(NDI_UNIQUE, 0,op,"%d KEY",i & PU_KEY?1:0); 1442 new_draw_info_format (NDI_UNIQUE, 0, op, "%d KEY", i & PU_KEY ? 1 : 0);
1293 1443
1294 new_draw_info_format(NDI_UNIQUE, 0,op,"%d MISSILEWEAPON",i & PU_MISSILEWEAPON?1:0); 1444 new_draw_info_format (NDI_UNIQUE, 0, op, "%d MISSILEWEAPON", i & PU_MISSILEWEAPON ? 1 : 0);
1295 new_draw_info_format(NDI_UNIQUE, 0,op,"%d ALLWEAPON",i & PU_ALLWEAPON?1:0); 1445 new_draw_info_format (NDI_UNIQUE, 0, op, "%d ALLWEAPON", i & PU_ALLWEAPON ? 1 : 0);
1296 new_draw_info_format(NDI_UNIQUE, 0,op,"%d MAGICAL",i & PU_MAGICAL?1:0); 1446 new_draw_info_format (NDI_UNIQUE, 0, op, "%d MAGICAL", i & PU_MAGICAL ? 1 : 0);
1297 new_draw_info_format(NDI_UNIQUE, 0,op,"%d POTION",i & PU_POTION?1:0); 1447 new_draw_info_format (NDI_UNIQUE, 0, op, "%d POTION", i & PU_POTION ? 1 : 0);
1298 1448
1299 new_draw_info_format(NDI_UNIQUE, 0,op,"%d SPELLBOOK",i & PU_SPELLBOOK?1:0); 1449 new_draw_info_format (NDI_UNIQUE, 0, op, "%d SPELLBOOK", i & PU_SPELLBOOK ? 1 : 0);
1300 new_draw_info_format(NDI_UNIQUE, 0,op,"%d SKILLSCROLL",i & PU_SKILLSCROLL?1:0); 1450 new_draw_info_format (NDI_UNIQUE, 0, op, "%d SKILLSCROLL", i & PU_SKILLSCROLL ? 1 : 0);
1301 new_draw_info_format(NDI_UNIQUE, 0,op,"%d READABLES",i & PU_READABLES?1:0); 1451 new_draw_info_format (NDI_UNIQUE, 0, op, "%d READABLES", i & PU_READABLES ? 1 : 0);
1302 new_draw_info_format(NDI_UNIQUE, 0,op,"%d MAGICDEVICE", i & PU_MAGIC_DEVICE?1:0); 1452 new_draw_info_format (NDI_UNIQUE, 0, op, "%d MAGICDEVICE", i & PU_MAGIC_DEVICE ? 1 : 0);
1303 1453
1304 new_draw_info_format(NDI_UNIQUE, 0,op,"%d NOT CURSED", i & PU_NOT_CURSED?1:0); 1454 new_draw_info_format (NDI_UNIQUE, 0, op, "%d NOT CURSED", i & PU_NOT_CURSED ? 1 : 0);
1305 1455
1306 new_draw_info_format(NDI_UNIQUE, 0,op,"%d JEWELS", i & PU_JEWELS?1:0); 1456 new_draw_info_format (NDI_UNIQUE, 0, op, "%d JEWELS", i & PU_JEWELS ? 1 : 0);
1457 new_draw_info_format (NDI_UNIQUE, 0, op, "%d FLESH", i & PU_FLESH ? 1 : 0);
1307 1458
1308 new_draw_info_format(NDI_UNIQUE, 0,op,""); 1459 new_draw_info_format (NDI_UNIQUE, 0, op, "");
1309 } 1460}
1310 1461
1462int
1311int command_pickup (object *op, char *params) 1463command_pickup (object *op, char *params)
1312{ 1464{
1313 uint32 i; 1465 uint32 i;
1314 static const char* names[ ] = { 1466 static const char *names[] = {
1315 "debug", "inhibit", "stop", "food", "drink", "valuables", "bow", "arrow", "helmet", 1467 "debug", "inhibit", "stop", "food", "drink", "valuables", "bow", "arrow", "helmet",
1316 "shield", "armour", "boots", "gloves", "cloak", "key", "missile", "allweapon", 1468 "shield", "armour", "boots", "gloves", "cloak", "key", "missile", "allweapon",
1317 "magical", "potion", "spellbook", "skillscroll", "readables", "magicdevice", "notcursed", "jewels", NULL }; 1469 "magical", "potion", "spellbook", "skillscroll", "readables", "magicdevice", "notcursed",
1470 "jewels", "flesh", NULL
1471 };
1318 static uint32 modes[ ] = { 1472 static uint32 modes[] = {
1319 PU_DEBUG, PU_INHIBIT, PU_STOP, PU_FOOD, PU_DRINK, PU_VALUABLES, PU_BOW, PU_ARROW, PU_HELMET, 1473 PU_DEBUG, PU_INHIBIT, PU_STOP, PU_FOOD, PU_DRINK, PU_VALUABLES, PU_BOW, PU_ARROW, PU_HELMET,
1320 PU_SHIELD, PU_ARMOUR, PU_BOOTS, PU_GLOVES, PU_CLOAK, PU_KEY, PU_MISSILEWEAPON, PU_ALLWEAPON, 1474 PU_SHIELD, PU_ARMOUR, PU_BOOTS, PU_GLOVES, PU_CLOAK, PU_KEY, PU_MISSILEWEAPON, PU_ALLWEAPON,
1321 PU_MAGICAL, PU_POTION, PU_SPELLBOOK, PU_SKILLSCROLL, PU_READABLES, PU_MAGIC_DEVICE, PU_NOT_CURSED, PU_JEWELS, 0 }; 1475 PU_MAGICAL, PU_POTION, PU_SPELLBOOK, PU_SKILLSCROLL, PU_READABLES, PU_MAGIC_DEVICE, PU_NOT_CURSED,
1476 PU_JEWELS, PU_FLESH, 0
1477 };
1322 1478
1323 if(!params) { 1479 if (!params)
1480 {
1324 /* if the new mode is used, just print the settings */ 1481 /* if the new mode is used, just print the settings */
1325 if(op->contr->mode & PU_NEWMODE) 1482 if (op->contr->mode & PU_NEWMODE)
1326 { 1483 {
1327 display_new_pickup( op ); 1484 display_new_pickup (op);
1328 return 1; 1485 return 1;
1329 } 1486 }
1487 if (1)
1330 if(1) LOG(llevDebug, "command_pickup: !params\n"); 1488 LOG (llevDebug, "command_pickup: !params\n");
1331 set_pickup_mode(op, (op->contr->mode > 6)? 0: op->contr->mode+1); 1489 set_pickup_mode (op, (op->contr->mode > 6) ? 0 : op->contr->mode + 1);
1332 return 0; 1490 return 0;
1333 } 1491 }
1334 1492
1335 while ( *params == ' ' && *params ) 1493 while (*params == ' ' && *params)
1336 params++; 1494 params++;
1337 1495
1338 if ( *params == '+' || *params == '-' ) 1496 if (*params == '+' || *params == '-')
1339 { 1497 {
1340 int mode; 1498 int mode;
1499
1341 for ( mode = 0; names[ mode ]; mode++ ) 1500 for (mode = 0; names[mode]; mode++)
1342 { 1501 {
1343 if ( !strcmp( names[ mode ], params + 1 ) ) 1502 if (!strcmp (names[mode], params + 1))
1344 { 1503 {
1345 i = op->contr->mode; 1504 i = op->contr->mode;
1346 if ( !( i & PU_NEWMODE ) ) 1505 if (!(i & PU_NEWMODE))
1347 i = PU_NEWMODE; 1506 i = PU_NEWMODE;
1348 if ( *params == '+' ) 1507 if (*params == '+')
1349 i = i | modes[ mode ]; 1508 i = i | modes[mode];
1350 else 1509 else
1351 i = i & ~modes[ mode ]; 1510 i = i & ~modes[mode];
1352 op->contr->mode = i; 1511 op->contr->mode = i;
1353 display_new_pickup( op ); 1512 display_new_pickup (op);
1354 return 1; 1513 return 1;
1355 } 1514 }
1356 } 1515 }
1357 new_draw_info_format( NDI_UNIQUE, 0, op, "Pickup: invalid item %s\n", params ); 1516 new_draw_info_format (NDI_UNIQUE, 0, op, "Pickup: invalid item %s\n", params);
1358 return 1; 1517 return 1;
1359 } 1518 }
1360 1519
1361 if(sscanf(params, "%u", &i) != 1) { 1520 if (sscanf (params, "%u", &i) != 1)
1521 {
1522 if (1)
1362 if(1) LOG(llevDebug, "command_pickup: params==NULL\n"); 1523 LOG (llevDebug, "command_pickup: params==NULL\n");
1363 new_draw_info(NDI_UNIQUE, 0,op,"Usage: pickup <0-7> or <value_density> ."); 1524 new_draw_info (NDI_UNIQUE, 0, op, "Usage: pickup <0-7> or <value_density> .");
1525 return 1;
1526 }
1527 set_pickup_mode (op, i);
1528
1529 return 1;
1530}
1531
1532void
1533set_pickup_mode (object *op, int i)
1534{
1535 switch (op->contr->mode = i)
1536 {
1537 case 0:
1538 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Don't pick up.");
1539 break;
1540 case 1:
1541 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up one item.");
1542 break;
1543 case 2:
1544 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up one item and stop.");
1545 break;
1546 case 3:
1547 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Stop before picking up.");
1548 break;
1549 case 4:
1550 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all items.");
1551 break;
1552 case 5:
1553 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all items and stop.");
1554 break;
1555 case 6:
1556 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all magic items.");
1557 break;
1558 case 7:
1559 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all coins and gems");
1560 break;
1561 }
1562}
1563
1564int
1565command_search_items (object *op, char *params)
1566{
1567 char buf[MAX_BUF];
1568
1569 if (settings.search_items == FALSE)
1364 return 1; 1570 return 1;
1571
1572 if (params == NULL)
1573 {
1574 if (op->contr->search_str[0] == '\0')
1575 {
1576 new_draw_info (NDI_UNIQUE, 0, op, "Example: search magic+1");
1577 new_draw_info (NDI_UNIQUE, 0, op, "Would automatically pick up all");
1578 new_draw_info (NDI_UNIQUE, 0, op, "items containing the word 'magic+1'.");
1579 return 1;
1580 }
1581 op->contr->search_str[0] = '\0';
1582 new_draw_info (NDI_UNIQUE, 0, op, "Search mode turned off.");
1583 fix_player (op);
1584 return 1;
1365 } 1585 }
1366 set_pickup_mode(op,i); 1586 if ((int) strlen (params) >= MAX_BUF)
1367 1587 {
1588 new_draw_info (NDI_UNIQUE, 0, op, "Search string too long.");
1589 return 1;
1590 }
1591 strcpy (op->contr->search_str, params);
1592 sprintf (buf, "Searching for '%s'.", op->contr->search_str);
1593 new_draw_info (NDI_UNIQUE, 0, op, buf);
1594 fix_player (op);
1368 return 1; 1595 return 1;
1369} 1596}
1370 1597
1371void set_pickup_mode(object *op,int i) {
1372 switch(op->contr->mode=i) {
1373 case 0:
1374 new_draw_info(NDI_UNIQUE, 0,op,"Mode: Don't pick up.");
1375 break;
1376 case 1:
1377 new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up one item.");
1378 break;
1379 case 2:
1380 new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up one item and stop.");
1381 break;
1382 case 3:
1383 new_draw_info(NDI_UNIQUE, 0,op,"Mode: Stop before picking up.");
1384 break;
1385 case 4:
1386 new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up all items.");
1387 break;
1388 case 5:
1389 new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up all items and stop.");
1390 break;
1391 case 6:
1392 new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up all magic items.");
1393 break;
1394 case 7:
1395 new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up all coins and gems");
1396 break;
1397 }
1398}
1399
1400int command_search_items (object *op, char *params)
1401{
1402 char buf[MAX_BUF];
1403
1404 if (settings.search_items == FALSE)
1405 return 1;
1406
1407 if(params == NULL) {
1408 if(op->contr->search_str[0]=='\0') {
1409 new_draw_info(NDI_UNIQUE, 0,op,"Example: search magic+1");
1410 new_draw_info(NDI_UNIQUE, 0,op,"Would automatically pick up all");
1411 new_draw_info(NDI_UNIQUE, 0,op,"items containing the word 'magic+1'.");
1412 return 1;
1413 }
1414 op->contr->search_str[0]='\0';
1415 new_draw_info(NDI_UNIQUE, 0,op,"Search mode turned off.");
1416 fix_player(op);
1417 return 1;
1418 }
1419 if((int)strlen(params) >= MAX_BUF) {
1420 new_draw_info(NDI_UNIQUE, 0,op,"Search string too long.");
1421 return 1;
1422 }
1423 strcpy(op->contr->search_str, params);
1424 sprintf(buf,"Searching for '%s'.",op->contr->search_str);
1425 new_draw_info(NDI_UNIQUE, 0,op,buf);
1426 fix_player(op);
1427 return 1;
1428}
1429
1430/*
1431 * Changing the custom name of an item
1432 *
1433 * Syntax is: rename <what object> to <new name>
1434 * if '<what object>' is omitted, marked object is used
1435 * if 'to <new name>' is omitted, custom name is cleared
1436 *
1437 * Names are considered for all purpose having a length <=127 (max length sent to client
1438 * by server) */
1439
1440int command_rename_item(object *op, char *params)
1441{
1442 char buf[VERY_BIG_BUF];
1443 int itemnumber;
1444 object *item=NULL;
1445 char *closebrace;
1446 size_t counter;
1447
1448 if (params) {
1449 /* Let's skip white spaces */
1450 while(' '==*params) params++;
1451
1452 /* Checking the first part */
1453 if ((itemnumber = atoi(params))!=0) {
1454 for (item=op->inv; item && ((item->count != itemnumber) || item->invisible); item=item->below);
1455 if (!item) {
1456 new_draw_info(NDI_UNIQUE,0,op,"Tried to rename an invalid item.");
1457 return 1;
1458 }
1459 while(isdigit(*params) || ' '==*params) params++;
1460 }
1461 else if ('<'==*params) {
1462 /* Got old name, let's get it & find appropriate matching item */
1463 closebrace=strchr(params,'>');
1464 if(!closebrace) {
1465 new_draw_info(NDI_UNIQUE,0,op,"Syntax error!");
1466 return 1;
1467 }
1468 /* Sanity check for buffer overruns */
1469 if((closebrace-params)>127) {
1470 new_draw_info(NDI_UNIQUE,0,op,"Old name too long (up to 127 characters allowed)!");
1471 return 1;
1472 }
1473 /* Copy the old name */
1474 strncpy(buf,params+1,closebrace-params-1);
1475 buf[closebrace-params-1]='\0';
1476
1477 /* Find best matching item */
1478 item=find_best_object_match(op,buf);
1479 if(!item) {
1480 new_draw_info(NDI_UNIQUE,0,op,"Could not find a matching item to rename.");
1481 return 1;
1482 }
1483
1484 /* Now need to move pointer to just after > */
1485 params=closebrace+1;
1486 while(' '==*params) params++;
1487
1488 } else {
1489 /* Use marked item */
1490 item=find_marked_object(op);
1491 if(!item) {
1492 new_draw_info(NDI_UNIQUE,0,op,"No marked item to rename.");
1493 return 1;
1494 }
1495 }
1496
1497 /* Now let's find the new name */
1498 if(!strncmp(params,"to ",3)) {
1499 params+=3;
1500 while(' '==*params) params++;
1501 if('<'!=*params) {
1502 new_draw_info(NDI_UNIQUE,0,op,"Syntax error, expecting < at start of new name!");
1503 return 1;
1504 }
1505 closebrace=strchr(params+1,'>');
1506 if(!closebrace) {
1507 new_draw_info(NDI_UNIQUE,0,op,"Syntax error, expecting > at end of new name!");
1508 return 1;
1509 }
1510
1511 /* Sanity check for buffer overruns */
1512 if((closebrace-params)>127) {
1513 new_draw_info(NDI_UNIQUE,0,op,"New name too long (up to 127 characters allowed)!");
1514 return 1;
1515 }
1516
1517 /* Copy the new name */
1518 strncpy(buf,params+1,closebrace-params-1);
1519 buf[closebrace-params-1]='\0';
1520
1521 /* Let's check it for weird characters */
1522 for(counter=0;counter<strlen(buf);counter++) {
1523 if(isalnum(buf[counter])) continue;
1524 if(' '==buf[counter]) continue;
1525 if('\''==buf[counter]) continue;
1526 if('+'==buf[counter]) continue;
1527 if('_'==buf[counter]) continue;
1528 if('-'==buf[counter]) continue;
1529
1530 /* If we come here, then the name contains an invalid character...
1531 tell the player & exit */
1532 new_draw_info(NDI_UNIQUE,0,op,"Invalid new name!");
1533 return 1;
1534 }
1535
1536 } else {
1537 /* If param contains something, then syntax error... */
1538 if(strlen(params)) {
1539 new_draw_info(NDI_UNIQUE,0,op,"Syntax error, expected 'to <' after old name!");
1540 return 1;
1541 }
1542 /* New name is empty */
1543 buf[0]='\0';
1544 }
1545 } else {
1546 /* Last case: params==NULL */
1547 item=find_marked_object(op);
1548 if(!item) {
1549 new_draw_info(NDI_UNIQUE,0,op,"No marked item to rename.");
1550 return 1;
1551 }
1552 buf[0]='\0';
1553 }
1554
1555 if (QUERY_FLAG(item, FLAG_UNPAID)) {
1556 new_draw_info(NDI_UNIQUE,0,op,"You can't rename an unpaid item! You should pay for it first.");
1557 return 1;
1558 }
1559
1560 /* Coming here, everything is fine... */
1561 if(!strlen(buf)) {
1562 /* Clear custom name */
1563 if(item->custom_name) {
1564 FREE_AND_CLEAR_STR(item->custom_name);
1565
1566 new_draw_info_format(NDI_UNIQUE, 0, op,"You stop calling your %s with weird names.",query_base_name(item,item->nrof>1?1:0));
1567 esrv_update_item(UPD_NAME,op,item);
1568 } else {
1569 new_draw_info(NDI_UNIQUE,0,op,"This item has no custom name.");
1570 }
1571 } else {
1572 /* Set custom name */
1573 FREE_AND_COPY(item->custom_name,buf);
1574
1575 new_draw_info_format(NDI_UNIQUE, 0, op,"Your %s will now be called %s.",query_base_name(item,item->nrof>1?1:0),buf);
1576 esrv_update_item(UPD_NAME,op,item);
1577 }
1578
1579 return 1;
1580}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines