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

Comparing deliantra/server/server/apply.C (file contents):
Revision 1.3 by elmex, Tue Aug 15 15:00:20 2006 UTC vs.
Revision 1.31 by root, Sun Dec 3 20:26:35 2006 UTC

1/*
2 * static char *rcsid_apply_c =
3 * "$Id: apply.C,v 1.3 2006/08/15 15:00:20 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) 2001 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001 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 authors can be reached via e-mail to crossfire-devel@real-time.com 21 The authors can be reached via e-mail to <crossfire@schmorp.de>
26*/ 22*/
27 23
28#include <global.h> 24#include <global.h>
29#include <living.h> 25#include <living.h>
30#include <spells.h> 26#include <spells.h>
31#include <skills.h> 27#include <skills.h>
32#include <tod.h> 28#include <tod.h>
33 29
34#ifndef __CEXTRACT__ 30#ifndef __CEXTRACT__
35#include <sproto.h> 31# include <sproto.h>
36#endif 32#endif
37 33
38/* Want this regardless of rplay. */ 34/* Want this regardless of rplay. */
39#include <sounds.h> 35#include <sounds.h>
40 36
41/* need math lib for double-precision and pow() in dragon_eat_flesh() */ 37/* need math lib for double-precision and pow() in dragon_eat_flesh() */
42#include <math.h> 38#include <math.h>
43
44/* Can transport hold object op?
45 * This is a pretty trivial function,
46 * but in the future, possible transport may have more restrictions
47 * or weight reduction like containers
48 */
49int transport_can_hold(const object *transport, const object *op, int nrof)
50{
51 if ((op->weight *nrof + transport->carrying) > transport->weight_limit)
52 return 0;
53 else
54 return 1;
55}
56
57
58/*
59 * Player is trying to use a transport. This returns same values as
60 * manual_apply() does. This function basically checks to see if
61 * the player can use the transport, and if so, sets up the appropriate
62 * pointers.
63 */
64int apply_transport(object *pl, object *transport, int aflag) {
65
66 /* Only players can use transports right now */
67 if (pl->type != PLAYER) return 0;
68
69 /* If player is currently on a transport but not this transport, they need
70 * to exit first. Perhaps transport to transport transfers should be
71 * allowed.
72 */
73 if (pl->contr->transport && pl->contr->transport != transport) {
74 new_draw_info_format(NDI_UNIQUE, 0, pl,
75 "You must exit %s before you can board %s.",
76 query_name(pl->contr->transport),
77 query_name(transport));
78 return 1;
79 }
80
81 /* player is currently on a transport. This must mean he
82 * wants to exit.
83 */
84 if (pl->contr->transport) {
85 object *old_transport = pl->contr->transport, *inv;
86
87 /* Should we print a message if the player only wants to
88 * apply?
89 */
90 if (aflag & AP_APPLY) return 1;
91 new_draw_info_format(NDI_UNIQUE, 0, pl,
92 "You disembark from %s.",
93 query_name(old_transport));
94 remove_ob(pl);
95 pl->map = old_transport->map;
96 pl->x = old_transport->x;
97 pl->y = old_transport->y;
98 if (pl->contr == old_transport->contr)
99 old_transport->contr = NULL;
100
101 pl->contr->transport = NULL;
102 insert_ob_in_map(pl, pl->map, pl, 0);
103 sum_weight(old_transport);
104
105 /* Possible for more than one player to be using a transport.
106 * if that is the case, we don't want to reset the face, as the
107 * transport is still occupied.
108 */
109 for (inv=old_transport->inv; inv; inv=inv->below)
110 if (inv->type == PLAYER) break;
111 if (!inv) {
112 old_transport->face = old_transport->arch->clone.face;
113 old_transport->animation_id = old_transport->arch->clone.animation_id;
114 }
115 return 1;
116 }
117 else {
118 /* player is trying to board a transport */
119 int pc=0, p_limit;
120 object *inv;
121 const char *kv;
122
123 if (aflag & AP_UNAPPLY) return 1;
124
125 /* Can this transport hold the weight of this player? */
126 if (!transport_can_hold(transport, pl, 1)) {
127 new_draw_info_format(NDI_UNIQUE, 0, pl,
128 "The %s is unable to hold your weight!",
129 query_name(transport));
130 return 1;
131 }
132
133 /* Does this transport have space for more players? */
134 for (inv=transport->inv; inv; inv=inv->below) {
135 if (inv->type == PLAYER) pc++;
136 }
137 kv = get_ob_key_value(transport, "passenger_limit");
138 if (!kv) p_limit=1;
139 else p_limit = atoi(kv);
140 if (pc >= p_limit) {
141 new_draw_info_format(NDI_UNIQUE, 0, pl,
142 "The %s does not have space for any more people",
143 query_name(transport));
144 return 1;
145 }
146
147 /* Everything checks out OK - player can get on the transport */
148 pl->contr->transport = transport;
149 if (!transport->contr) transport->contr = pl->contr;
150 remove_ob(pl);
151 insert_ob_in_ob(pl, transport);
152 sum_weight(transport);
153 pl->map = transport->map;
154 pl->x = transport->x;
155 pl->y = transport->y;
156
157 /* Might need to update face, animation info */
158 if (!pc) {
159 const char *str;
160
161 str = get_ob_key_value(transport, "face_full");
162 if (str)
163 transport->face = &new_faces[FindFace(str,
164 transport->face->number)];
165 str = get_ob_key_value(transport, "anim_full");
166 if (str)
167 transport->animation_id = find_animation(str);
168 }
169
170 /* Does speed of this object change based on weight? */
171 kv = get_ob_key_value(transport, "weight_speed_ratio");
172 if (kv) {
173 int wsr = atoi(kv);
174 float base_speed;
175
176 kv = get_ob_key_value(transport, "base_speed");
177 if (kv) base_speed = atof(kv);
178 else base_speed = transport->arch->clone.speed;
179
180 transport->speed = base_speed - (base_speed * transport->carrying *
181 wsr) / (transport->weight_limit * 100);
182
183 /* Put some limits on min/max speeds */
184 if (transport->speed < 0.10) transport->speed = 0.10;
185 if (transport->speed > 1.0) transport->speed = 1.0;
186 }
187 } /* else if player is boarding the transport */
188
189 return 1;
190}
191
192
193 39
194/** 40/**
195 * Check if op should abort moving victim because of it's race or slaying. 41 * Check if op should abort moving victim because of it's race or slaying.
196 * Returns 1 if it should abort, returns 0 if it should continue. 42 * Returns 1 if it should abort, returns 0 if it should continue.
197 */ 43 */
44int
198int should_director_abort(object *op, object *victim) 45should_director_abort (object *op, object *victim)
199{ 46{
200 int arch_flag, name_flag, race_flag; 47 int arch_flag, name_flag, race_flag;
48
201 /* Get flags to determine what of arch, name, and race should be checked. 49 /* Get flags to determine what of arch, name, and race should be checked.
202 * This is stored in subtype, and is a bitmask, the LSB is the arch flag, 50 * This is stored in subtype, and is a bitmask, the LSB is the arch flag,
203 * the next is the name flag, and the last is the race flag. Also note, 51 * the next is the name flag, and the last is the race flag. Also note,
204 * if subtype is set to zero, that also goes to defaults of all affecting 52 * if subtype is set to zero, that also goes to defaults of all affecting
205 * it. Examples: 53 * it. Examples:
206 * subtype 1: only arch 54 * subtype 1: only arch
207 * subtype 3: arch or name 55 * subtype 3: arch or name
208 * subtype 5: arch or race 56 * subtype 5: arch or race
209 * subtype 7: all three 57 * subtype 7: all three
210 */ 58 */
211 if (op->subtype) 59 if (op->subtype)
212 { 60 {
213 arch_flag = (op->subtype & 1); 61 arch_flag = (op->subtype & 1);
214 name_flag = (op->subtype & 2); 62 name_flag = (op->subtype & 2);
215 race_flag = (op->subtype & 4); 63 race_flag = (op->subtype & 4);
216 } else { 64 }
65 else
66 {
217 arch_flag = 1; 67 arch_flag = 1;
218 name_flag = 1; 68 name_flag = 1;
219 race_flag = 1; 69 race_flag = 1;
220 } 70 }
221 /* If the director has race set, only affect objects with a arch, 71 /* If the director has race set, only affect objects with a arch,
222 * name or race that matches. 72 * name or race that matches.
223 */ 73 */
224 if ( (op->race) && 74 if ((op->race) &&
225 ((!(victim->arch && arch_flag && victim->arch->name) || strcmp(op->race, victim->arch->name))) && 75 ((!(victim->arch && arch_flag && victim->arch->name) || strcmp (op->race, victim->arch->name))) &&
226 ((!(victim->name && name_flag) || strcmp(op->race, victim->name))) && 76 ((!(victim->name && name_flag) || strcmp (op->race, victim->name))) &&
227 ((!(victim->race && race_flag) || strcmp(op->race, victim->race))) ) { 77 ((!(victim->race && race_flag) || strcmp (op->race, victim->race))))
78 {
228 return 1; 79 return 1;
229 } 80 }
230 /* If the director has slaying set, only affect objects where none 81 /* If the director has slaying set, only affect objects where none
231 * of arch, name, or race match. 82 * of arch, name, or race match.
232 */ 83 */
233 if ( (op->slaying) && (
234 ((victim->arch && arch_flag && victim->arch->name && !strcmp(op->slaying, victim->arch->name))) || 84 if ((op->slaying) && (((victim->arch && arch_flag && victim->arch->name && !strcmp (op->slaying, victim->arch->name))) ||
235 ((victim->name && name_flag && !strcmp(op->slaying, victim->name))) || 85 ((victim->name && name_flag && !strcmp (op->slaying, victim->name))) ||
236 ((victim->race && race_flag && !strcmp(op->slaying, victim->race)))) ) { 86 ((victim->race && race_flag && !strcmp (op->slaying, victim->race)))))
87 {
237 return 1; 88 return 1;
238 } 89 }
239 return 0; 90 return 0;
240} 91}
241 92
242/** 93/**
243 * This handles a player dropping money on an altar to identify stuff. 94 * This handles a player dropping money on an altar to identify stuff.
244 * It'll identify marked item, if none all items up to dropped money. 95 * It'll identify marked item, if none all items up to dropped money.
245 * Return value: 1 if money was destroyed, 0 if not. 96 * Return value: 1 if money was destroyed, 0 if not.
246 */ 97 */
98static int
247static int apply_id_altar (object *money, object *altar, object *pl) 99apply_id_altar (object *money, object *altar, object *pl)
248{ 100{
249 object *id, *marked; 101 object *id, *marked;
250 int success=0; 102 int success = 0;
251 103
252 if (pl == NULL || pl->type != PLAYER) 104 if (pl == NULL || pl->type != PLAYER)
253 return 0; 105 return 0;
254 106
255 /* Check for MONEY type is a special hack - it prevents 'nothing needs 107 /* Check for MONEY type is a special hack - it prevents 'nothing needs
256 * identifying' from being printed out more than it needs to be. 108 * identifying' from being printed out more than it needs to be.
257 */ 109 */
258 if ( ! check_altar_sacrifice (altar, money) || money->type != MONEY) 110 if (!check_altar_sacrifice (altar, money) || money->type != MONEY)
259 return 0; 111 return 0;
260 112
261 marked = find_marked_object (pl); 113 marked = find_marked_object (pl);
262 /* if the player has a marked item, identify that if it needs to be 114 /* if the player has a marked item, identify that if it needs to be
263 * identified. IF it doesn't, then go through the player inventory. 115 * identified. IF it doesn't, then go through the player inventory.
264 */ 116 */
265 if (marked && ! QUERY_FLAG (marked, FLAG_IDENTIFIED) 117 if (marked && !QUERY_FLAG (marked, FLAG_IDENTIFIED) && need_identify (marked))
266 && need_identify (marked))
267 { 118 {
268 if (operate_altar (altar, &money)) { 119 if (operate_altar (altar, &money))
120 {
269 identify (marked); 121 identify (marked);
270 new_draw_info_format(NDI_UNIQUE, 0, pl, 122 new_draw_info_format (NDI_UNIQUE, 0, pl, "You have %s.", long_desc (marked, pl));
271 "You have %s.", long_desc(marked, pl));
272 if (marked->msg) { 123 if (marked->msg)
124 {
273 new_draw_info(NDI_UNIQUE, 0,pl, "The item has a story:"); 125 new_draw_info (NDI_UNIQUE, 0, pl, "The item has a story:");
274 new_draw_info(NDI_UNIQUE, 0,pl, marked->msg); 126 new_draw_info (NDI_UNIQUE, 0, pl, marked->msg);
127 }
128 return money == NULL;
129 }
275 } 130 }
276 return money == NULL;
277 }
278 }
279 131
280 for (id=pl->inv; id; id=id->below) { 132 for (id = pl->inv; id; id = id->below)
133 {
281 if (!QUERY_FLAG(id, FLAG_IDENTIFIED) && !id->invisible && 134 if (!QUERY_FLAG (id, FLAG_IDENTIFIED) && !id->invisible && need_identify (id))
282 need_identify(id)) { 135 {
283 if (operate_altar(altar,&money)) { 136 if (operate_altar (altar, &money))
284 identify(id); 137 {
285 new_draw_info_format(NDI_UNIQUE, 0, pl, 138 identify (id);
286 "You have %s.", long_desc(id, pl)); 139 new_draw_info_format (NDI_UNIQUE, 0, pl, "You have %s.", long_desc (id, pl));
287 if (id->msg) { 140 if (id->msg)
141 {
288 new_draw_info(NDI_UNIQUE, 0,pl, "The item has a story:"); 142 new_draw_info (NDI_UNIQUE, 0, pl, "The item has a story:");
289 new_draw_info(NDI_UNIQUE, 0,pl, id->msg); 143 new_draw_info (NDI_UNIQUE, 0, pl, id->msg);
290 } 144 }
291 success=1; 145 success = 1;
292 /* If no more money, might as well quit now */ 146 /* If no more money, might as well quit now */
293 if (money == NULL || ! check_altar_sacrifice (altar,money)) 147 if (money == NULL || !check_altar_sacrifice (altar, money))
294 break; 148 break;
295 } 149 }
296 else { 150 else
151 {
297 LOG(llevError,"check_id_altar: Couldn't do sacrifice when we should have been able to\n"); 152 LOG (llevError, "check_id_altar: Couldn't do sacrifice when we should have been able to\n");
298 break; 153 break;
299 } 154 }
300 } 155 }
301 } 156 }
157 if (!success)
302 if (!success) new_draw_info(NDI_UNIQUE, 0,pl,"You have nothing that needs identifying"); 158 new_draw_info (NDI_UNIQUE, 0, pl, "You have nothing that needs identifying");
303 return money == NULL; 159 return money == NULL;
304} 160}
305 161
306/** 162/**
307 * This checks whether the object has a "on_use_yield" field, and if so generated and drops 163 * This checks whether the object has a "on_use_yield" field, and if so generated and drops
308 * matching item. 164 * matching item.
309 **/ 165 **/
166static void
310static void handle_apply_yield(object* tmp) 167handle_apply_yield (object *tmp)
311{ 168{
312 const char* yield; 169 const char *yield;
313 170
314 yield = get_ob_key_value(tmp,"on_use_yield"); 171 yield = get_ob_key_value (tmp, "on_use_yield");
315 if (yield != NULL) 172 if (yield != NULL)
316 { 173 {
317 object* drop = get_archetype(yield); 174 object *drop = get_archetype (yield);
175
318 if (tmp->env) 176 if (tmp->env)
319 { 177 {
320 drop = insert_ob_in_ob(drop,tmp->env); 178 drop = insert_ob_in_ob (drop, tmp->env);
321 if (tmp->env->type == PLAYER) 179 if (tmp->env->type == PLAYER)
322 esrv_send_item(tmp->env,drop); 180 esrv_send_item (tmp->env, drop);
323 } 181 }
324 else 182 else
325 { 183 {
326 drop->x = tmp->x; 184 drop->x = tmp->x;
327 drop->y = tmp->y; 185 drop->y = tmp->y;
328 insert_ob_in_map(drop,tmp->map,tmp,INS_BELOW_ORIGINATOR); 186 insert_ob_in_map (drop, tmp->map, tmp, INS_BELOW_ORIGINATOR);
329 } 187 }
330 } 188 }
331} 189}
332 190
333/** 191/**
334 * Handles applying a potion. 192 * Handles applying a potion.
335 */ 193 */
194int
336int apply_potion (object * op, object * tmp) 195apply_potion (object *op, object *tmp)
337{ 196{
338 int got_one = 0, i; 197 int got_one = 0, i;
339 object *force = 0, *floor = 0; 198 object *force = 0, *floor = 0;
340 199
341 floor = get_map_ob (op->map, op->x, op->y); 200 floor = get_map_ob (op->map, op->x, op->y);
342 201
343 if (!(get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE_MAP)) 202 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE)
344 { 203 {
345 if (op->type == PLAYER) 204 if (op->type == PLAYER)
346 { 205 new_draw_info (NDI_UNIQUE, 0, op, "Gods prevent you from using this here, it's sacred ground!");
206 CLEAR_FLAG (tmp, FLAG_APPLIED);
207 return 0;
208 }
209
210 if (op->type == PLAYER)
211 {
347 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 212 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
348 identify (tmp); 213 identify (tmp);
349 } 214 }
350 215
351 handle_apply_yield (tmp); 216 handle_apply_yield (tmp);
352 217
353 /* Potion of restoration - only for players */ 218 /* Potion of restoration - only for players */
354 if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE)) 219 if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE))
355 { 220 {
356 object *depl; 221 object *depl;
357 archetype *at; 222 archetype *at;
358 223
224 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
225 {
226 drain_stat (op);
227 fix_player (op);
228 decrease_ob (tmp);
229 return 1;
230 }
231 if ((at = archetype::find (ARCH_DEPLETION)) == NULL)
232 {
233 LOG (llevError, "Could not find archetype depletion\n");
234 return 0;
235 }
236 depl = present_arch_in_ob (at, op);
237 if (depl != NULL)
238 {
239 for (i = 0; i < NUM_STATS; i++)
240 if (get_attr_value (&depl->stats, i))
241 {
242 new_draw_info (NDI_UNIQUE, 0, op, restore_msg[i]);
243 }
244 remove_ob (depl);
245 free_object (depl);
246 fix_player (op);
247 }
248 else
249 new_draw_info (NDI_UNIQUE, 0, op, "You potion had no effect.");
250
251 decrease_ob (tmp);
252 return 1;
253 }
254
255 /* improvement potion - only for players */
256 if (op->type == PLAYER && tmp->attacktype & AT_GODPOWER)
257 {
258
259 for (i = 1; i < MIN (11, op->level); i++)
260 {
359 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 261 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
360 { 262 {
361 drain_stat (op); 263 if (op->contr->levhp[i] != 1)
362 fix_player (op);
363 decrease_ob (tmp);
364 return 1;
365 }
366 if ((at = find_archetype (ARCH_DEPLETION)) == NULL)
367 {
368 LOG (llevError, "Could not find archetype depletion\n");
369 return 0;
370 }
371 depl = present_arch_in_ob (at, op);
372 if (depl != NULL)
373 {
374 for (i = 0; i < NUM_STATS; i++)
375 if (get_attr_value (&depl->stats, i))
376 { 264 {
377 new_draw_info (NDI_UNIQUE, 0, op, restore_msg[i]); 265 op->contr->levhp[i] = 1;
266 break;
378 } 267 }
379 remove_ob (depl); 268 if (op->contr->levsp[i] != 1)
380 free_object (depl); 269 {
381 fix_player (op); 270 op->contr->levsp[i] = 1;
271 break;
272 }
273 if (op->contr->levgrace[i] != 1)
274 {
275 op->contr->levgrace[i] = 1;
276 break;
277 }
382 } 278 }
383 else 279 else
384 new_draw_info (NDI_UNIQUE, 0, op, "You potion had no effect.");
385
386 decrease_ob (tmp);
387 return 1;
388 }
389
390 /* improvement potion - only for players */
391 if (op->type == PLAYER && tmp->attacktype & AT_GODPOWER)
392 {
393
394 for (i = 1; i < MIN (11, op->level); i++)
395 { 280 {
396 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 281 if (op->contr->levhp[i] < 9)
397 { 282 {
398 if (op->contr->levhp[i] != 1)
399 {
400 op->contr->levhp[i] = 1; 283 op->contr->levhp[i] = 9;
401 break; 284 break;
402 }
403 if (op->contr->levsp[i] != 1)
404 {
405 op->contr->levsp[i] = 1;
406 break;
407 }
408 if (op->contr->levgrace[i] != 1)
409 {
410 op->contr->levgrace[i] = 1;
411 break;
412 }
413 } 285 }
414 else 286 if (op->contr->levsp[i] < 6)
415 { 287 {
416 if (op->contr->levhp[i] < 9)
417 {
418 op->contr->levhp[i] = 9;
419 break;
420 }
421 if (op->contr->levsp[i] < 6)
422 {
423 op->contr->levsp[i] = 6; 288 op->contr->levsp[i] = 6;
424 break; 289 break;
425 } 290 }
426 if (op->contr->levgrace[i] < 3) 291 if (op->contr->levgrace[i] < 3)
427 { 292 {
428 op->contr->levgrace[i] = 3; 293 op->contr->levgrace[i] = 3;
429 break; 294 break;
430 }
431 } 295 }
432 } 296 }
297 }
433 /* Just makes checking easier */ 298 /* Just makes checking easier */
434 if (i < MIN (11, op->level)) 299 if (i < MIN (11, op->level))
435 got_one = 1; 300 got_one = 1;
436 if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED)) 301 if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED))
302 {
303 if (got_one)
437 { 304 {
438 if (got_one)
439 {
440 fix_player (op); 305 fix_player (op);
441 new_draw_info (NDI_UNIQUE, 0, op, 306 new_draw_info (NDI_UNIQUE, 0, op, "The Gods smile upon you and remake you");
442 "The Gods smile upon you and remake you"); 307 new_draw_info (NDI_UNIQUE, 0, op, "a little more in their image.");
443 new_draw_info (NDI_UNIQUE, 0, op, 308 new_draw_info (NDI_UNIQUE, 0, op, "You feel a little more perfect.");
444 "a little more in their image.");
445 new_draw_info (NDI_UNIQUE, 0, op,
446 "You feel a little more perfect.");
447 }
448 else
449 new_draw_info (NDI_UNIQUE, 0, op,
450 "The potion had no effect - you are already perfect");
451 } 309 }
452 else 310 else
311 new_draw_info (NDI_UNIQUE, 0, op, "The potion had no effect - you are already perfect");
312 }
313 else
453 { /* cursed potion */ 314 { /* cursed potion */
454 if (got_one) 315 if (got_one)
455 {
456 fix_player (op);
457 new_draw_info (NDI_UNIQUE, 0, op,
458 "The Gods are angry and punish you.");
459 }
460 else
461 new_draw_info (NDI_UNIQUE, 0, op,
462 "You are fortunate that you are so pathetic.");
463 }
464 decrease_ob (tmp);
465 return 1;
466 }
467
468
469 /* A potion that casts a spell. Healing, restore spellpoint (power potion)
470 * and heroism all fit into this category. Given the spell object code,
471 * there is no limit to the number of spells that potions can be cast,
472 * but direction is problematic to try and imbue fireball potions for example.
473 */
474 if (tmp->inv)
475 {
476 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
477 { 316 {
478 object *fball; 317 fix_player (op);
479 318 new_draw_info (NDI_UNIQUE, 0, op, "The Gods are angry and punish you.");
480 new_draw_info (NDI_UNIQUE, 0, op, "Yech! Your lungs are on fire!");
481 /* Explodes a fireball centered at player */
482 fball = get_archetype (EXPLODING_FIREBALL);
483 fball->dam_modifier =
484 random_roll (1, op->level, op, PREFER_LOW) / 5 + 1;
485 fball->stats.maxhp =
486 random_roll (1, op->level, op, PREFER_LOW) / 10 + 2;
487 fball->x = op->x;
488 fball->y = op->y;
489 insert_ob_in_map (fball, op->map, NULL, 0);
490 } 319 }
491 else 320 else
321 new_draw_info (NDI_UNIQUE, 0, op, "You are fortunate that you are so pathetic.");
322 }
323 decrease_ob (tmp);
324 return 1;
325 }
326
327
328 /* A potion that casts a spell. Healing, restore spellpoint (power potion)
329 * and heroism all fit into this category. Given the spell object code,
330 * there is no limit to the number of spells that potions can be cast,
331 * but direction is problematic to try and imbue fireball potions for example.
332 */
333 if (tmp->inv)
334 {
335 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
336 {
337 object *fball;
338
339 new_draw_info (NDI_UNIQUE, 0, op, "Yech! Your lungs are on fire!");
340 /* Explodes a fireball centered at player */
341 fball = get_archetype (EXPLODING_FIREBALL);
342 fball->dam_modifier = random_roll (1, op->level, op, PREFER_LOW) / 5 + 1;
343 fball->stats.maxhp = random_roll (1, op->level, op, PREFER_LOW) / 10 + 2;
344 fball->x = op->x;
345 fball->y = op->y;
346 insert_ob_in_map (fball, op->map, NULL, 0);
347 }
348 else
492 cast_spell (op, tmp, op->facing, tmp->inv, NULL); 349 cast_spell (op, tmp, op->facing, tmp->inv, NULL);
493 350
494 decrease_ob (tmp); 351 decrease_ob (tmp);
495 /* if youre dead, no point in doing this... */ 352 /* if youre dead, no point in doing this... */
496 if (!QUERY_FLAG (op, FLAG_REMOVED)) 353 if (!QUERY_FLAG (op, FLAG_REMOVED))
497 fix_player (op); 354 fix_player (op);
498 return 1; 355 return 1;
499 } 356 }
500 357
501 /* Deal with protection potions */ 358 /* Deal with protection potions */
502 force = NULL; 359 force = NULL;
503 for (i = 0; i < NROFATTACKS; i++) 360 for (i = 0; i < NROFATTACKS; i++)
504 { 361 {
505 if (tmp->resist[i]) 362 if (tmp->resist[i])
506 { 363 {
507 if (!force) 364 if (!force)
508 force = get_archetype (FORCE_NAME); 365 force = get_archetype (FORCE_NAME);
509 memcpy (force->resist, tmp->resist, sizeof (tmp->resist)); 366 memcpy (force->resist, tmp->resist, sizeof (tmp->resist));
510 force->type = POTION_EFFECT; 367 force->type = POTION_EFFECT;
511 break; /* Only need to find one protection since we copy entire batch */ 368 break; /* Only need to find one protection since we copy entire batch */
512 } 369 }
513 } 370 }
514 /* This is a protection potion */ 371 /* This is a protection potion */
515 if (force) 372 if (force)
516 { 373 {
517 /* cursed items last longer */ 374 /* cursed items last longer */
518 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 375 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
519 { 376 {
520 force->stats.food *= 10; 377 force->stats.food *= 10;
521 for (i = 0; i < NROFATTACKS; i++) 378 for (i = 0; i < NROFATTACKS; i++)
522 if (force->resist[i] > 0) 379 if (force->resist[i] > 0)
523 force->resist[i] = -force->resist[i]; /* prot => vuln */ 380 force->resist[i] = -force->resist[i]; /* prot => vuln */
524 } 381 }
525 force->speed_left = -1; 382 force->speed_left = -1;
526 force = insert_ob_in_ob (force, op); 383 force = insert_ob_in_ob (force, op);
384 CLEAR_FLAG (tmp, FLAG_APPLIED);
385 SET_FLAG (force, FLAG_APPLIED);
386 change_abil (op, force);
387 decrease_ob (tmp);
388 return 1;
389 }
390
391 /* Only thing left are the stat potions */
392 if (op->type == PLAYER)
393 { /* only for players */
394 if ((QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) && tmp->value != 0)
527 CLEAR_FLAG (tmp, FLAG_APPLIED); 395 CLEAR_FLAG (tmp, FLAG_APPLIED);
528 SET_FLAG (force, FLAG_APPLIED);
529 change_abil (op, force);
530 decrease_ob (tmp);
531 return 1;
532 }
533
534 /* Only thing left are the stat potions */
535 if (op->type == PLAYER)
536 { /* only for players */
537 if ((QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
538 && tmp->value != 0)
539 CLEAR_FLAG (tmp, FLAG_APPLIED);
540 else 396 else
541 SET_FLAG (tmp, FLAG_APPLIED); 397 SET_FLAG (tmp, FLAG_APPLIED);
542 if (!change_abil (op, tmp)) 398 if (!change_abil (op, tmp))
543 new_draw_info (NDI_UNIQUE, 0, op, "Nothing happened."); 399 new_draw_info (NDI_UNIQUE, 0, op, "Nothing happened.");
544 }
545 }
546 else
547 {
548 if (op->type == PLAYER)
549 new_draw_info (NDI_UNIQUE, 0, op,
550 "Gods prevent you from using the potion on this sacred ground"
551 );
552 return 0;
553 } 400 }
554 401
555 /* CLEAR_FLAG is so that if the character has other potions 402 /* CLEAR_FLAG is so that if the character has other potions
556 * that were grouped with the one consumed, his 403 * that were grouped with the one consumed, his
557 * stat will not be raised by them. fix_player just clears 404 * stat will not be raised by them. fix_player just clears
568 ****************************************************************************/ 415 ****************************************************************************/
569 416
570/** 417/**
571 * This returns the sum of nrof of item (arch name). 418 * This returns the sum of nrof of item (arch name).
572 */ 419 */
420static int
573static int check_item(object *op, const char *item) 421check_item (object *op, const char *item)
574{ 422{
575 int count=0; 423 int count = 0;
576 424
577 425
578 if (item==NULL) return 0; 426 if (item == NULL)
427 return 0;
579 op=op->below; 428 op = op->below;
580 while(op!=NULL) { 429 while (op != NULL)
430 {
581 if (strcmp(op->arch->name,item)==0){ 431 if (strcmp (op->arch->name, item) == 0)
432 {
582 if (!QUERY_FLAG (op, FLAG_CURSED) && !QUERY_FLAG (op, FLAG_DAMNED) 433 if (!QUERY_FLAG (op, FLAG_CURSED) && !QUERY_FLAG (op, FLAG_DAMNED)
583 /* Loophole bug? -FD- */ && !QUERY_FLAG (op, FLAG_UNPAID) ) 434 /* Loophole bug? -FD- */ && !QUERY_FLAG (op, FLAG_UNPAID))
584 { 435 {
585 if (op->nrof == 0)/* this is necessary for artifact sacrifices --FD-- */ 436 if (op->nrof == 0) /* this is necessary for artifact sacrifices --FD-- */
586 count++; 437 count++;
587 else 438 else
588 count += op->nrof; 439 count += op->nrof;
440 }
441 }
442 op = op->below;
589 } 443 }
590 }
591 op=op->below;
592 }
593 return count; 444 return count;
594} 445}
595 446
596/** 447/**
597 * This removes 'nrof' of what item->slaying says to remove. 448 * This removes 'nrof' of what item->slaying says to remove.
598 * op is typically the player, which is only 449 * op is typically the player, which is only
599 * really used to determine what space to look at. 450 * really used to determine what space to look at.
600 * Modified to only eat 'nrof' of objects. 451 * Modified to only eat 'nrof' of objects.
601 */ 452 */
453static void
602static void eat_item(object *op,const char *item, uint32 nrof) 454eat_item (object *op, const char *item, uint32 nrof)
603{ 455{
604 object *prev; 456 object *prev;
605 457
458 prev = op;
459 op = op->below;
460
461 while (op != NULL)
462 {
463 if (strcmp (op->arch->name, item) == 0)
464 {
465 if (op->nrof >= nrof)
466 {
467 decrease_ob_nr (op, nrof);
468 return;
469 }
470 else
471 {
472 decrease_ob_nr (op, op->nrof);
473 nrof -= op->nrof;
474 }
475 op = prev;
476 }
606 prev = op; 477 prev = op;
607 op=op->below; 478 op = op->below;
608
609 while(op!=NULL) {
610 if (strcmp(op->arch->name,item)==0) {
611 if (op->nrof >= nrof) {
612 decrease_ob_nr(op,nrof);
613 return;
614 } else {
615 decrease_ob_nr(op,op->nrof);
616 nrof -= op->nrof;
617 }
618 op=prev;
619 }
620 prev = op;
621 op=op->below;
622 } 479 }
623} 480}
624 481
625/** 482/**
626 * This checks to see of the player (who) is sufficient level to use a weapon 483 * This checks to see of the player (who) is sufficient level to use a weapon
627 * with improvs improvements (typically last_eat). We take an int here 484 * with improvs improvements (typically last_eat). We take an int here
628 * instead of the object so that the improvement code can pass along the 485 * instead of the object so that the improvement code can pass along the
629 * increased value to see if the object is usuable. 486 * increased value to see if the object is usuable.
630 * we return 1 (true) if the player can use the weapon. 487 * we return 1 (true) if the player can use the weapon.
631 */ 488 */
489static int
632static int check_weapon_power(const object *who, int improvs) 490check_weapon_power (const object *who, int improvs)
633{ 491{
492
634/* Old code is below (commented out). Basically, since weapons are the only 493/* Old code is below (commented out). Basically, since weapons are the only
635 * object players really have any control to improve, it's a bit harsh to 494 * object players really have any control to improve, it's a bit harsh to
636 * require high level in some combat skill, so we just use overall level. 495 * require high level in some combat skill, so we just use overall level.
637 */ 496 */
638#if 1 497#if 1
639 if (((who->level/5)+5) >= improvs) return 1; 498 if (((who->level / 5) + 5) >= improvs)
499 return 1;
500 else
640 else return 0; 501 return 0;
641 502
642#else 503#else
643 int level=0; 504 int level = 0;
644 505
645 /* The skill system hands out wc and dam bonuses to fighters 506 /* The skill system hands out wc and dam bonuses to fighters
646 * more generously than the old system (see fix_player). Thus 507 * more generously than the old system (see fix_player). Thus
647 * we need to curtail the power of player enchanted weapons. 508 * we need to curtail the power of player enchanted weapons.
648 * I changed this to 1 improvement per "fighter" level/5 -b.t. 509 * I changed this to 1 improvement per "fighter" level/5 -b.t.
649 * Note: Nothing should break by allowing this ratio to be different or 510 * Note: Nothing should break by allowing this ratio to be different or
650 * using normal level - it is just a matter of play balance. 511 * using normal level - it is just a matter of play balance.
651 */ 512 */
652 if(who->type==PLAYER) { 513 if (who->type == PLAYER)
514 {
653 object *wc_obj=NULL; 515 object *wc_obj = NULL;
654 516
655 for(wc_obj=who->inv;wc_obj;wc_obj=wc_obj->below) 517 for (wc_obj = who->inv; wc_obj; wc_obj = wc_obj->below)
656 if (wc_obj->type == SKILL && IS_COMBAT_SKILL(wc_obj->subtype) && wc_obj->level > level) 518 if (wc_obj->type == SKILL && IS_COMBAT_SKILL (wc_obj->subtype) && wc_obj->level > level)
657 level = wc_obj->level; 519 level = wc_obj->level;
658 520
659 if (!level ) { 521 if (!level)
522 {
660 LOG(llevError,"Error: Player: %s lacks wc experience object\n",who->name); 523 LOG (llevError, "Error: Player: %s lacks wc experience object\n", who->name);
524 level = who->level;
525 }
526 }
527 else
661 level = who->level; 528 level = who->level;
662 }
663 }
664 else
665 level=who->level;
666 529
667 return (improvs <= ((level/5)+5)); 530 return (improvs <= ((level / 5) + 5));
668#endif 531#endif
669} 532}
670 533
671/** 534/**
672 * Returns how many items of type improver->slaying there are under op. 535 * Returns how many items of type improver->slaying there are under op.
673 * Will display a message if none found, and 1 if improver->slaying is NULL. 536 * Will display a message if none found, and 1 if improver->slaying is NULL.
674 */ 537 */
538static int
675static int check_sacrifice(object *op, const object *improver) 539check_sacrifice (object *op, const object *improver)
676{ 540{
677 int count=0; 541 int count = 0;
678 542
679 if (improver->slaying!=NULL) { 543 if (improver->slaying != NULL)
544 {
680 count = check_item(op,improver->slaying); 545 count = check_item (op, improver->slaying);
681 if (count<1) { 546 if (count < 1)
547 {
682 char buf[200]; 548 char buf[200];
549
683 sprintf(buf,"The gods want more %ss",improver->slaying); 550 sprintf (buf, "The gods want more %ss", &improver->slaying);
684 new_draw_info(NDI_UNIQUE,0,op,buf); 551 new_draw_info (NDI_UNIQUE, 0, op, buf);
685 return 0; 552 return 0;
686 } 553 }
687 } 554 }
688 else 555 else
689 count=1; 556 count = 1;
690 557
691 return count; 558 return count;
692} 559}
693 560
694/** 561/**
695 * Actually improves the weapon, and tells user. 562 * Actually improves the weapon, and tells user.
696 */ 563 */
697int improve_weapon_stat(object *op,object *improver,object *weapon, 564int
698 signed char *stat,int sacrifice_count,const char *statname) 565improve_weapon_stat (object *op, object *improver, object *weapon, signed char *stat, int sacrifice_count, const char *statname)
699{ 566{
700 567
701 new_draw_info(NDI_UNIQUE,0,op,"Your sacrifice was accepted."); 568 new_draw_info (NDI_UNIQUE, 0, op, "Your sacrifice was accepted.");
702 *stat += sacrifice_count; 569 *stat += sacrifice_count;
703 weapon->last_eat++; 570 weapon->last_eat++;
704 new_draw_info_format(NDI_UNIQUE,0,op, 571 new_draw_info_format (NDI_UNIQUE, 0, op, "Weapon's bonus to %s improved by %d", statname, sacrifice_count);
705 "Weapon's bonus to %s improved by %d",statname,sacrifice_count);
706 decrease_ob(improver); 572 decrease_ob (improver);
707 573
708 /* So it updates the players stats and the window */ 574 /* So it updates the players stats and the window */
709 fix_player(op); 575 fix_player (op);
710 return 1; 576 return 1;
711} 577}
712 578
713/* Types of improvements, hidden in the sp field. */ 579/* Types of improvements, hidden in the sp field. */
714#define IMPROVE_PREPARE 1 580#define IMPROVE_PREPARE 1
727/** 593/**
728 * This does the prepare weapon scroll. 594 * This does the prepare weapon scroll.
729 * Checks for sacrifice, and so on. 595 * Checks for sacrifice, and so on.
730 */ 596 */
731 597
598int
732int prepare_weapon(object *op, object *improver, object *weapon) 599prepare_weapon (object *op, object *improver, object *weapon)
733{ 600{
734 int sacrifice_count,i; 601 int sacrifice_count, i;
735 char buf[MAX_BUF]; 602 char buf[MAX_BUF];
736 603
737 if (weapon->level!=0) { 604 if (weapon->level != 0)
605 {
738 new_draw_info(NDI_UNIQUE,0,op,"Weapon already prepared."); 606 new_draw_info (NDI_UNIQUE, 0, op, "Weapon already prepared.");
739 return 0; 607 return 0;
740 } 608 }
741 for (i=0; i<NROFATTACKS; i++) 609 for (i = 0; i < NROFATTACKS; i++)
742 if (weapon->resist[i]) break; 610 if (weapon->resist[i])
611 break;
743 612
744 /* If we break out, i will be less than nrofattacks, preventing 613 /* If we break out, i will be less than nrofattacks, preventing
745 * improvement of items that already have protections. 614 * improvement of items that already have protections.
746 */ 615 */
747 if (i<NROFATTACKS || 616 if (i < NROFATTACKS || weapon->stats.hp || /* regeneration */
748 weapon->stats.hp || /* regeneration */
749 (weapon->stats.sp && weapon->type == WEAPON) || /* sp regeneration */ 617 (weapon->stats.sp && weapon->type == WEAPON) || /* sp regeneration */
750 weapon->stats.exp || /* speed */ 618 weapon->stats.exp || /* speed */
751 weapon->stats.ac) /* AC - only taifu's I think */ 619 weapon->stats.ac) /* AC - only taifu's I think */
752 { 620 {
753 new_draw_info(NDI_UNIQUE,0,op,"Cannot prepare magic weapons."); 621 new_draw_info (NDI_UNIQUE, 0, op, "Cannot prepare magic weapons.");
754 return 0; 622 return 0;
755 } 623 }
756 sacrifice_count=check_sacrifice(op,improver); 624 sacrifice_count = check_sacrifice (op, improver);
757 if (sacrifice_count<=0) 625 if (sacrifice_count <= 0)
758 return 0; 626 return 0;
759 weapon->level=isqrt(sacrifice_count); 627 weapon->level = isqrt (sacrifice_count);
760 new_draw_info(NDI_UNIQUE,0,op,"Your sacrifice was accepted."); 628 new_draw_info (NDI_UNIQUE, 0, op, "Your sacrifice was accepted.");
761 eat_item(op, improver->slaying, sacrifice_count); 629 eat_item (op, improver->slaying, sacrifice_count);
762 630
763 new_draw_info_format(NDI_UNIQUE, 0, op,"Your *%s may be improved %d times.", 631 new_draw_info_format (NDI_UNIQUE, 0, op, "Your *%s may be improved %d times.", &weapon->name, weapon->level);
764 weapon->name,weapon->level);
765 632
766 sprintf(buf,"%s's %s",op->name,weapon->name); 633 sprintf (buf, "%s's %s", &op->name, &weapon->name);
767 FREE_AND_COPY(weapon->name, buf); 634 weapon->name = weapon->name_pl = buf;
768 FREE_AND_COPY(weapon->name_pl, buf);
769 weapon->nrof=0; /* prevents preparing n weapons in the same 635 weapon->nrof = 0; /* prevents preparing n weapons in the same
770 slot at once! */ 636 slot at once! */
771 decrease_ob(improver); 637 decrease_ob (improver);
772 weapon->last_eat=0; 638 weapon->last_eat = 0;
773 return 1; 639 return 1;
774} 640}
775 641
776 642
777/** 643/**
778 * Does the dirty job for 'improve weapon' scroll, prepare or add something. 644 * Does the dirty job for 'improve weapon' scroll, prepare or add something.
783 * 649 *
784 * We are hiding extra information about the weapon in the level and 650 * We are hiding extra information about the weapon in the level and
785 * last_eat numbers for an object. Hopefully this won't break anything ?? 651 * last_eat numbers for an object. Hopefully this won't break anything ??
786 * level == max improve last_eat == current improve 652 * level == max improve last_eat == current improve
787 */ 653 */
654int
788int improve_weapon(object *op,object *improver,object *weapon) 655improve_weapon (object *op, object *improver, object *weapon)
789{ 656{
790 int sacrifice_count, sacrifice_needed=0; 657 int sacrifice_count, sacrifice_needed = 0;
791 658
792 if(improver->stats.sp==IMPROVE_PREPARE) { 659 if (improver->stats.sp == IMPROVE_PREPARE)
660 {
793 return prepare_weapon(op, improver, weapon); 661 return prepare_weapon (op, improver, weapon);
794 } 662 }
795 if (weapon->level==0) { 663 if (weapon->level == 0)
664 {
796 new_draw_info(NDI_UNIQUE, 0,op,"This weapon has not been prepared."); 665 new_draw_info (NDI_UNIQUE, 0, op, "This weapon has not been prepared.");
797 return 0; 666 return 0;
798 } 667 }
799 if (weapon->level==weapon->last_eat && weapon->item_power >=100) { 668 if (weapon->level == weapon->last_eat && weapon->item_power >= 100)
669 {
800 new_draw_info(NDI_UNIQUE, 0,op,"This weapon cannot be improved any more."); 670 new_draw_info (NDI_UNIQUE, 0, op, "This weapon cannot be improved any more.");
801 return 0; 671 return 0;
802 } 672 }
803 if (QUERY_FLAG(weapon, FLAG_APPLIED) && 673 if (QUERY_FLAG (weapon, FLAG_APPLIED) && !check_weapon_power (op, weapon->last_eat + 1))
804 !check_weapon_power(op, weapon->last_eat+1)) { 674 {
805 new_draw_info(NDI_UNIQUE, 0,op,"Improving the weapon will make it too"); 675 new_draw_info (NDI_UNIQUE, 0, op, "Improving the weapon will make it too");
806 new_draw_info(NDI_UNIQUE, 0,op,"powerful for you to use. Unready it if you"); 676 new_draw_info (NDI_UNIQUE, 0, op, "powerful for you to use. Unready it if you");
807 new_draw_info(NDI_UNIQUE, 0,op,"really want to improve it."); 677 new_draw_info (NDI_UNIQUE, 0, op, "really want to improve it.");
808 return 0; 678 return 0;
809 } 679 }
810 /* This just increases damage by 5 points, no matter what. No sacrifice 680 /* This just increases damage by 5 points, no matter what. No sacrifice
811 * is needed. Since stats.dam is now a 16 bit value and not 8 bit, 681 * is needed. Since stats.dam is now a 16 bit value and not 8 bit,
812 * don't put any maximum value on damage - the limit is how much the 682 * don't put any maximum value on damage - the limit is how much the
813 * weapon can be improved. 683 * weapon can be improved.
814 */ 684 */
815 if (improver->stats.sp==IMPROVE_DAMAGE) { 685 if (improver->stats.sp == IMPROVE_DAMAGE)
686 {
816 weapon->stats.dam += 5; 687 weapon->stats.dam += 5;
817 weapon->weight += 5000; /* 5 KG's */ 688 weapon->weight += 5000; /* 5 KG's */
818 new_draw_info_format(NDI_UNIQUE, 0, op, 689 new_draw_info_format (NDI_UNIQUE, 0, op, "Damage has been increased by 5 to %d", weapon->stats.dam);
819 "Damage has been increased by 5 to %d", weapon->stats.dam);
820 weapon->last_eat++; 690 weapon->last_eat++;
821 691
822 weapon->item_power++; 692 weapon->item_power++;
823 decrease_ob(improver); 693 decrease_ob (improver);
824 return 1; 694 return 1;
825 } 695 }
826 if (improver->stats.sp == IMPROVE_WEIGHT) { 696 if (improver->stats.sp == IMPROVE_WEIGHT)
697 {
827 /* Reduce weight by 20% */ 698 /* Reduce weight by 20% */
828 weapon->weight = (weapon->weight * 8)/10; 699 weapon->weight = (weapon->weight * 8) / 10;
829 if (weapon->weight < 1) weapon->weight = 1; 700 if (weapon->weight < 1)
830 new_draw_info_format(NDI_UNIQUE, 0, op, 701 weapon->weight = 1;
831 "Weapon weight reduced to %6.1f kg", 702 new_draw_info_format (NDI_UNIQUE, 0, op, "Weapon weight reduced to %6.1f kg", (float) weapon->weight / 1000.0);
832 (float)weapon->weight/1000.0);
833 weapon->last_eat++; 703 weapon->last_eat++;
834 weapon->item_power++; 704 weapon->item_power++;
835 decrease_ob(improver); 705 decrease_ob (improver);
836 return 1; 706 return 1;
837 } 707 }
838 if (improver->stats.sp == IMPROVE_ENCHANT) { 708 if (improver->stats.sp == IMPROVE_ENCHANT)
709 {
839 weapon->magic++; 710 weapon->magic++;
840 weapon->last_eat++; 711 weapon->last_eat++;
841 new_draw_info_format(NDI_UNIQUE, 0, op 712 new_draw_info_format (NDI_UNIQUE, 0, op, "Weapon magic increased to %d", weapon->magic);
842 ,"Weapon magic increased to %d",weapon->magic);
843 decrease_ob(improver); 713 decrease_ob (improver);
844 weapon->item_power++; 714 weapon->item_power++;
845 return 1; 715 return 1;
846 } 716 }
847 717
848 sacrifice_needed = weapon->stats.Str + weapon->stats.Int + weapon->stats.Dex+ 718 sacrifice_needed = weapon->stats.Str + weapon->stats.Int + weapon->stats.Dex +
849 weapon->stats.Pow + weapon->stats.Con + weapon->stats.Cha + 719 weapon->stats.Pow + weapon->stats.Con + weapon->stats.Cha + weapon->stats.Wis;
850 weapon->stats.Wis;
851 720
852 if (sacrifice_needed<1) 721 if (sacrifice_needed < 1)
853 sacrifice_needed =1; 722 sacrifice_needed = 1;
854 sacrifice_needed *=2; 723 sacrifice_needed *= 2;
855 724
856 sacrifice_count = check_sacrifice(op,improver); 725 sacrifice_count = check_sacrifice (op, improver);
857 if (sacrifice_count < sacrifice_needed) { 726 if (sacrifice_count < sacrifice_needed)
858 new_draw_info_format(NDI_UNIQUE, 0, op, 727 {
859 "You need at least %d %s", sacrifice_needed, improver->slaying); 728 new_draw_info_format (NDI_UNIQUE, 0, op, "You need at least %d %s", sacrifice_needed, &improver->slaying);
860 return 0; 729 return 0;
861 } 730 }
862 eat_item(op,improver->slaying, sacrifice_needed); 731 eat_item (op, improver->slaying, sacrifice_needed);
863 weapon->item_power++; 732 weapon->item_power++;
864 733
865 switch (improver->stats.sp) { 734 switch (improver->stats.sp)
735 {
866 case IMPROVE_STR: 736 case IMPROVE_STR:
867 return improve_weapon_stat(op,improver,weapon, 737 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Str), 1, "strength");
868 (signed char *) &(weapon->stats.Str),
869 1, "strength");
870 case IMPROVE_DEX: 738 case IMPROVE_DEX:
871 return improve_weapon_stat(op,improver,weapon, 739 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Dex), 1, "dexterity");
872 (signed char *) &(weapon->stats.Dex),
873 1, "dexterity");
874 case IMPROVE_CON: 740 case IMPROVE_CON:
875 return improve_weapon_stat(op,improver,weapon, 741 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Con), 1, "constitution");
876 (signed char *) &(weapon->stats.Con),
877 1, "constitution");
878 case IMPROVE_WIS: 742 case IMPROVE_WIS:
879 return improve_weapon_stat(op,improver,weapon, 743 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Wis), 1, "wisdom");
880 (signed char *) &(weapon->stats.Wis),
881 1, "wisdom");
882 case IMPROVE_CHA: 744 case IMPROVE_CHA:
883 return improve_weapon_stat(op,improver,weapon, 745 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Cha), 1, "charisma");
884 (signed char *) &(weapon->stats.Cha),
885 1, "charisma");
886 case IMPROVE_INT: 746 case IMPROVE_INT:
887 return improve_weapon_stat(op,improver,weapon, 747 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Int), 1, "intelligence");
888 (signed char *) &(weapon->stats.Int),
889 1, "intelligence");
890 case IMPROVE_POW: 748 case IMPROVE_POW:
891 return improve_weapon_stat(op,improver,weapon, 749 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Pow), 1, "power");
892 (signed char *) &(weapon->stats.Pow),
893 1, "power");
894 default: 750 default:
895 new_draw_info(NDI_UNIQUE, 0,op,"Unknown improvement type."); 751 new_draw_info (NDI_UNIQUE, 0, op, "Unknown improvement type.");
896 } 752 }
897 LOG(llevError,"improve_weapon: Got to end of function\n"); 753 LOG (llevError, "improve_weapon: Got to end of function\n");
898 return 0; 754 return 0;
899} 755}
900 756
901/** 757/**
902 * Handles the applying of improve/prepare/enchant weapon scroll. 758 * Handles the applying of improve/prepare/enchant weapon scroll.
903 * Checks a few things (not on a non-magic square, marked weapon, ...), 759 * Checks a few things (not on a non-magic square, marked weapon, ...),
904 * then calls improve_weapon to do the dirty work. 760 * then calls improve_weapon to do the dirty work.
905 */ 761 */
762int
906int check_improve_weapon (object *op, object *tmp) 763check_improve_weapon (object *op, object *tmp)
907{ 764{
908 object *otmp; 765 object *otmp;
909 766
910 if(op->type!=PLAYER) 767 if (op->type != PLAYER)
768 return 0;
769 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC))
770 {
771 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the scroll.");
911 return 0; 772 return 0;
912 if (!QUERY_FLAG(op, FLAG_WIZCAST) && (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC)) {
913 new_draw_info(NDI_UNIQUE, 0,op,"Something blocks the magic of the scroll.");
914 return 0;
915 } 773 }
916 otmp=find_marked_object(op); 774 otmp = find_marked_object (op);
917 if(!otmp) { 775 if (!otmp)
776 {
918 new_draw_info(NDI_UNIQUE, 0, op, "You need to mark a weapon object."); 777 new_draw_info (NDI_UNIQUE, 0, op, "You need to mark a weapon object.");
919 return 0; 778 return 0;
920 } 779 }
921 if (otmp->type != WEAPON && otmp->type != BOW) { 780 if (otmp->type != WEAPON && otmp->type != BOW)
781 {
922 new_draw_info(NDI_UNIQUE, 0,op,"Marked item is not a weapon or bow"); 782 new_draw_info (NDI_UNIQUE, 0, op, "Marked item is not a weapon or bow");
923 return 0; 783 return 0;
924 } 784 }
925 new_draw_info(NDI_UNIQUE, 0,op,"Applied weapon builder."); 785 new_draw_info (NDI_UNIQUE, 0, op, "Applied weapon builder.");
926 improve_weapon(op,tmp,otmp); 786 improve_weapon (op, tmp, otmp);
927 esrv_send_item(op, otmp); 787 esrv_send_item (op, otmp);
928 return 1; 788 return 1;
929} 789}
930 790
931/** 791/**
932 * This code deals with the armour improvment scrolls. 792 * This code deals with the armour improvment scrolls.
933 * Change limits on improvement - let players go up to 793 * Change limits on improvement - let players go up to
948 * the armour value of the piece of equipment exceed either 808 * the armour value of the piece of equipment exceed either
949 * the users level or 90) 809 * the users level or 90)
950 * Modified by MSW for partial resistance. Only support 810 * Modified by MSW for partial resistance. Only support
951 * changing of physical area right now. 811 * changing of physical area right now.
952 */ 812 */
813int
953int improve_armour(object *op, object *improver, object *armour) 814improve_armour (object *op, object *improver, object *armour)
954{ 815{
955 object *tmp; 816 object *tmp;
956 817
957 if (armour->magic >= settings.armor_max_enchant) { 818 if (armour->magic >= settings.armor_max_enchant)
819 {
958 new_draw_info(NDI_UNIQUE, 0,op,"This armour can not be enchanted any further."); 820 new_draw_info (NDI_UNIQUE, 0, op, "This armour can not be enchanted any further.");
959 return 0; 821 return 0;
960 } 822 }
961 /* Dealing with random artifact armor is a lot trickier (in terms of value, weight, 823 /* Dealing with random artifact armor is a lot trickier (in terms of value, weight,
962 * etc), so take the easy way out and don't worry about it. 824 * etc), so take the easy way out and don't worry about it.
963 * Note - maybe add scrolls which make the random artifact versions (eg, armour 825 * Note - maybe add scrolls which make the random artifact versions (eg, armour
964 * of gnarg and what not?) 826 * of gnarg and what not?)
965 */ 827 */
966 if (armour->title) { 828 if (armour->title)
829 {
967 new_draw_info(NDI_UNIQUE, 0, op, "This armour will not accept further enchantment."); 830 new_draw_info (NDI_UNIQUE, 0, op, "This armour will not accept further enchantment.");
968 return 0; 831 return 0;
969 } 832 }
970 833
971 /* Split objects if needed. Can't insert tmp until the 834 /* Split objects if needed. Can't insert tmp until the
972 * end of this function - otherwise it will just re-merge. 835 * end of this function - otherwise it will just re-merge.
973 */ 836 */
974 if(armour->nrof > 1) 837 if (armour->nrof > 1)
975 tmp = get_split_ob(armour,armour->nrof - 1); 838 tmp = get_split_ob (armour, armour->nrof - 1);
976 else 839 else
977 tmp = NULL; 840 tmp = NULL;
978 841
979 armour->magic++; 842 armour->magic++;
980 843
981 if ( !settings.armor_speed_linear ) 844 if (!settings.armor_speed_linear)
982 { 845 {
983 int base = 100; 846 int base = 100;
984 int pow = 0; 847 int pow = 0;
848
985 while ( pow < armour->magic ) 849 while (pow < armour->magic)
986 { 850 {
987 base = base - ( base * settings.armor_speed_improvement ) / 100; 851 base = base - (base * settings.armor_speed_improvement) / 100;
988 pow++; 852 pow++;
989 } 853 }
990 854
991 ARMOUR_SPEED( armour ) = ( ARMOUR_SPEED( &armour->arch->clone ) * base ) / 100; 855 ARMOUR_SPEED (armour) = (ARMOUR_SPEED (&armour->arch->clone) * base) / 100;
992 } 856 }
993 else 857 else
994 ARMOUR_SPEED( armour ) = ( ARMOUR_SPEED( &armour->arch->clone ) * ( 100 + armour->magic * settings.armor_speed_improvement ) )/100; 858 ARMOUR_SPEED (armour) = (ARMOUR_SPEED (&armour->arch->clone) * (100 + armour->magic * settings.armor_speed_improvement)) / 100;
995 859
996 if ( !settings.armor_weight_linear ) 860 if (!settings.armor_weight_linear)
997 { 861 {
998 int base = 100; 862 int base = 100;
999 int pow = 0; 863 int pow = 0;
864
1000 while ( pow < armour->magic ) 865 while (pow < armour->magic)
1001 { 866 {
1002 base = base - ( base * settings.armor_weight_reduction ) / 100; 867 base = base - (base * settings.armor_weight_reduction) / 100;
1003 pow++; 868 pow++;
1004 } 869 }
1005 870
1006 armour->weight = ( armour->arch->clone.weight * base ) / 100; 871 armour->weight = (armour->arch->clone.weight * base) / 100;
1007 } 872 }
1008 else 873 else
1009 armour->weight = ( armour->arch->clone.weight * ( 100 - armour->magic * settings.armor_weight_reduction ) ) / 100; 874 armour->weight = (armour->arch->clone.weight * (100 - armour->magic * settings.armor_weight_reduction)) / 100;
1010 875
1011 if ( armour->weight <= 0 ) 876 if (armour->weight <= 0)
1012 { 877 {
1013 LOG( llevInfo, "Warning: enchanted armours can have negative weight\n." ); 878 LOG (llevInfo, "Warning: enchanted armours can have negative weight\n.");
1014 armour->weight = 1; 879 armour->weight = 1;
1015 } 880 }
1016 881
1017 armour->item_power = get_power_from_ench(armour->arch->clone.item_power + armour->magic); 882 armour->item_power = get_power_from_ench (armour->arch->clone.item_power + armour->magic);
1018 883
1019 if (op->type == PLAYER) { 884 if (op->type == PLAYER)
885 {
1020 esrv_send_item(op, armour); 886 esrv_send_item (op, armour);
1021 if(QUERY_FLAG(armour, FLAG_APPLIED)) 887 if (QUERY_FLAG (armour, FLAG_APPLIED))
1022 fix_player(op); 888 fix_player (op);
1023 } 889 }
1024 decrease_ob(improver); 890 decrease_ob (improver);
1025 if (tmp) { 891 if (tmp)
892 {
1026 insert_ob_in_ob(tmp, op); 893 insert_ob_in_ob (tmp, op);
1027 esrv_send_item(op, tmp); 894 esrv_send_item (op, tmp);
1028 } 895 }
1029 return 1; 896 return 1;
1030} 897}
1031 898
1032 899
1033/* 900/*
1034 * convert_item() returns 1 if anything was converted, 0 if the item was not 901 * convert_item() returns 1 if anything was converted, 0 if the item was not
1042/* Takes one items and makes another. 909/* Takes one items and makes another.
1043 * converter is the object that is doing the conversion. 910 * converter is the object that is doing the conversion.
1044 * item is the object that triggered the converter - if it is not 911 * item is the object that triggered the converter - if it is not
1045 * what the converter wants, this will not do anything. 912 * what the converter wants, this will not do anything.
1046 */ 913 */
914int
1047int convert_item(object *item, object *converter) { 915convert_item (object *item, object *converter)
916{
1048 int nr=0; 917 int nr = 0;
1049 object *tmp;
1050 int is_in_shop;
1051 uint32 price_in; 918 uint32 price_in;
1052 919
1053 for(tmp = get_map_ob(converter->map, converter->x, converter->y);
1054 tmp != NULL;
1055 tmp = tmp->above) {
1056 if(tmp->type == SHOP_FLOOR)
1057 break;
1058 }
1059 is_in_shop = (tmp != NULL);
1060
1061 /* We make some assumptions - we assume if it takes money as it type, 920 /* We make some assumptions - we assume if it takes money as it type,
1062 * it wants some amount. We don't make change (ie, if something costs 921 * it wants some amount. We don't make change (ie, if something costs
1063 * 3 gp and player drops a platinum, tough luck) 922 * 3 gp and player drops a platinum, tough luck)
1064 */ 923 */
1065 if (!strcmp(CONV_FROM(converter),"money")) { 924 if (!strcmp (CONV_FROM (converter), "money"))
1066 int cost; 925 {
926 int cost;
1067 927
1068 if(item->type!=MONEY) 928 if (item->type != MONEY)
1069 return 0; 929 return 0;
1070 930
1071 nr=(item->nrof*item->value)/CONV_NEED(converter); 931 nr = (item->nrof * item->value) / CONV_NEED (converter);
1072 if (!nr) return 0; 932 if (!nr)
933 return 0;
1073 cost=nr*CONV_NEED(converter)/item->value; 934 cost = nr * CONV_NEED (converter) / item->value;
1074 /* take into account rounding errors */ 935 /* take into account rounding errors */
1075 if (nr*CONV_NEED(converter)%item->value) cost++; 936 if (nr * CONV_NEED (converter) % item->value)
937 cost++;
1076 decrease_ob_nr(item, cost); 938 decrease_ob_nr (item, cost);
1077 939
1078 price_in = cost*item->value; 940 price_in = cost * item->value;
941 }
942 else
1079 } 943 {
1080 else {
1081 if(item->type==PLAYER||CONV_FROM(converter)!=item->arch->name|| 944 if (item->type == PLAYER || CONV_FROM (converter) != item->arch->name ||
1082 (CONV_NEED(converter)&&CONV_NEED(converter)>item->nrof)) 945 (CONV_NEED (converter) && CONV_NEED (converter) > (uint16) item->nrof))
1083 return 0; 946 return 0;
1084 947
1085 if(CONV_NEED(converter)) { 948 if (CONV_NEED (converter))
949 {
1086 nr=item->nrof/CONV_NEED(converter); 950 nr = item->nrof / CONV_NEED (converter);
1087 decrease_ob_nr(item,nr*CONV_NEED(converter)); 951 decrease_ob_nr (item, nr * CONV_NEED (converter));
1088 price_in = nr*CONV_NEED(converter)*item->value; 952 price_in = nr * CONV_NEED (converter) * item->value;
1089 } else { 953 }
954 else
955 {
1090 price_in = item->value; 956 price_in = item->value;
1091 remove_ob(item); 957 remove_ob (item);
1092 free_object(item); 958 free_object (item);
1093 } 959 }
1094 } 960 }
1095 961
1096 if (converter->inv != NULL) { 962 if (converter->inv != NULL)
963 {
1097 object *ob; 964 object *ob;
1098 int i; 965 int i;
1099 object *ob_to_copy; 966 object *ob_to_copy;
1100 967
1101 /* select random object from inventory to copy */ 968 /* select random object from inventory to copy */
1102 ob_to_copy = converter->inv; 969 ob_to_copy = converter->inv;
1103 for (ob = converter->inv->below, i = 1; ob != NULL; ob = ob->below, i++) { 970 for (ob = converter->inv->below, i = 1; ob != NULL; ob = ob->below, i++)
971 {
1104 if (rndm(0, i) == 0) { 972 if (rndm (0, i) == 0)
1105 ob_to_copy = ob; 973 {
974 ob_to_copy = ob;
975 }
976 }
977 item = object_create_clone (ob_to_copy);
978 CLEAR_FLAG (item, FLAG_IS_A_TEMPLATE);
979 unflag_inv (item, FLAG_IS_A_TEMPLATE);
1106 } 980 }
1107 } 981 else
1108 item = object_create_clone(ob_to_copy); 982 {
1109 CLEAR_FLAG(item, FLAG_IS_A_TEMPLATE);
1110 unflag_inv(item, FLAG_IS_A_TEMPLATE);
1111 } else {
1112 if (converter->other_arch == NULL) { 983 if (converter->other_arch == NULL)
1113 LOG(llevError,"move_creator: Converter doesn't have other arch set: %s (%s, %d, %d)\n", converter->name ? converter->name : "(null)", converter->map->path, converter->x, converter->y); 984 {
985 LOG (llevError, "move_creator: Converter doesn't have other arch set: %s (%s, %d, %d)\n",
986 &converter->name, converter->map->path, converter->x, converter->y);
1114 return -1; 987 return -1;
1115 } 988 }
1116 989
1117 item = object_create_arch(converter->other_arch); 990 item = object_create_arch (converter->other_arch);
1118 fix_generated_item(item, converter, 0, 0, GT_MINIMAL); 991 fix_generated_item (item, converter, 0, 0, GT_MINIMAL);
1119 } 992 }
1120 993
1121 if(CONV_NR(converter)) 994 if (CONV_NR (converter))
1122 item->nrof=CONV_NR(converter); 995 item->nrof = CONV_NR (converter);
1123 if(nr) 996 if (nr)
1124 item->nrof*=nr; 997 item->nrof *= nr;
1125 if(is_in_shop) 998 if (is_in_shop (converter))
1126 SET_FLAG(item,FLAG_UNPAID); 999 SET_FLAG (item, FLAG_UNPAID);
1127 else if(price_in < item->nrof*item->value) { 1000 else if (price_in < item->nrof * item->value)
1001 {
1128 LOG(llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n", 1002 LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n",
1129 converter->name, converter->map->path, converter->x, converter->y, price_in, 1003 &converter->name, converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name);
1130 item->nrof*item->value, item->name); 1004
1131 /** 1005 /**
1132 * elmex: we are going to let the game continue, as the mapcreator 1006 * elmex: we are going to let the game continue, as the mapcreator
1133 * propably had something in mind when doing this 1007 * propably had something in mind when doing this
1134 */ 1008 */
1135 } 1009 }
1136 insert_ob_in_map_at(item, converter->map, converter, 0, converter->x, converter->y); 1010 insert_ob_in_map_at (item, converter->map, converter, 0, converter->x, converter->y);
1137 return 1; 1011 return 1;
1138} 1012}
1139 1013
1140/** 1014/**
1141 * Handle apply on containers. 1015 * Handle apply on containers.
1142 * By Eneq(@csd.uu.se). 1016 * By Eneq(@csd.uu.se).
1143 * Moved to own function and added many features [Tero.Haatanen@lut.fi] 1017 * Moved to own function and added many features [Tero.Haatanen@lut.fi]
1144 * added the alchemical cauldron to the code -b.t. 1018 * added the alchemical cauldron to the code -b.t.
1145 */ 1019 */
1146 1020
1021int
1147int apply_container (object *op, object *sack) 1022apply_container (object *op, object *sack)
1148{ 1023{
1149 char buf[MAX_BUF]; 1024 char buf[MAX_BUF];
1150 object *tmp; 1025 object *tmp;
1151 1026
1152 if(op->type!=PLAYER) 1027 if (op->type != PLAYER)
1153 return 0; /* This might change */ 1028 return 0; /* This might change */
1154 1029
1155 if (sack==NULL || sack->type != CONTAINER) { 1030 if (sack == NULL || sack->type != CONTAINER)
1031 {
1156 LOG (llevError, "apply_container: %s is not container!\n",sack?sack->name:"NULL"); 1032 LOG (llevError, "apply_container: %s is not container!\n", &sack->name);
1157 return 0; 1033 return 0;
1158 } 1034 }
1159 op->contr->last_used = NULL; 1035 op->contr->last_used = NULL;
1160 op->contr->last_used_id = 0; 1036 op->contr->last_used_id = 0;
1161 1037
1162 if (sack->env!=op) { 1038 if (sack->env != op)
1039 {
1163 if (sack->other_arch == NULL || sack->env != NULL) { 1040 if (sack->other_arch == NULL || sack->env != NULL)
1041 {
1164 new_draw_info(NDI_UNIQUE, 0,op,"You must get it first."); 1042 new_draw_info (NDI_UNIQUE, 0, op, "You must get it first.");
1165 return 1; 1043 return 1;
1166 } 1044 }
1167 /* It's on the ground, the problems begin */ 1045 /* It's on the ground, the problems begin */
1168 if (op->container != sack) { 1046 if (op->container != sack)
1047 {
1169 /* it's closed OR some player has opened it */ 1048 /* it's closed OR some player has opened it */
1170 if (QUERY_FLAG(sack, FLAG_APPLIED)) { 1049 if (QUERY_FLAG (sack, FLAG_APPLIED))
1171 for(tmp=get_map_ob(sack->map, sack->x, sack->y); 1050 {
1172 tmp && tmp->container != sack; tmp=tmp->above); 1051 for (tmp = get_map_ob (sack->map, sack->x, sack->y); tmp && tmp->container != sack; tmp = tmp->above);
1173 if (tmp) { 1052 if (tmp)
1053 {
1174 /* some other player have opened it */ 1054 /* some other player have opened it */
1175 new_draw_info_format(NDI_UNIQUE, 0, op, 1055 new_draw_info_format (NDI_UNIQUE, 0, op, "%s is already occupied.", query_name (sack));
1176 "%s is already occupied.", query_name(sack)); 1056 return 1;
1177 return 1; 1057 }
1178 } 1058 }
1179 } 1059 }
1180 }
1181 if ( QUERY_FLAG(sack, FLAG_APPLIED)) {
1182 if (op->container == NULL) {
1183 tmp = arch_to_object (sack->other_arch);
1184 /* not good, but insert_ob_in_ob() is too smart */
1185 CLEAR_FLAG (tmp, FLAG_REMOVED);
1186 tmp->x= tmp->y = tmp->ox = tmp->oy = 0;
1187 tmp->map = NULL;
1188 tmp->env = sack;
1189 if (sack->inv)
1190 sack->inv->above = tmp;
1191 tmp->below = sack->inv;
1192 tmp->above = NULL;
1193 sack->inv = tmp;
1194 sack->move_off = MOVE_ALL; /* trying force closing it */
1195 } else {
1196 sack->move_off = 0;
1197 tmp = sack->inv;
1198 if (tmp && tmp->type == CLOSE_CON) {
1199 remove_ob(tmp);
1200 free_object (tmp);
1201 }
1202 }
1203 }
1204 }
1205
1206 if (QUERY_FLAG (sack, FLAG_APPLIED)) { 1060 if (QUERY_FLAG (sack, FLAG_APPLIED))
1207 if (op->container) { 1061 {
1208 if (op->container != sack) { 1062 if (op->container == NULL)
1209 tmp = op->container; 1063 {
1210 apply_container (op, tmp); 1064 tmp = arch_to_object (sack->other_arch);
1211 sprintf (buf, "You close %s and open ", query_name(tmp)); 1065 /* not good, but insert_ob_in_ob() is too smart */
1212 op->container = sack; 1066 CLEAR_FLAG (tmp, FLAG_REMOVED);
1213 strcat (buf, query_name(sack)); 1067 tmp->x = tmp->y = 0;
1214 strcat (buf, "."); 1068 tmp->map = NULL;
1215 } else { 1069 tmp->env = sack;
1216 CLEAR_FLAG (sack, FLAG_APPLIED); 1070 if (sack->inv)
1217 op->container = NULL; 1071 sack->inv->above = tmp;
1218 sprintf (buf, "You close %s.", query_name(sack)); 1072 tmp->below = sack->inv;
1073 tmp->above = NULL;
1074 sack->inv = tmp;
1075 sack->move_off = MOVE_ALL; /* trying force closing it */
1076 }
1077 else
1078 {
1079 sack->move_off = 0;
1080 tmp = sack->inv;
1081 if (tmp && tmp->type == CLOSE_CON)
1082 {
1083 remove_ob (tmp);
1084 free_object (tmp);
1085 }
1086 }
1087 }
1219 } 1088 }
1220 } else { 1089
1090 if (QUERY_FLAG (sack, FLAG_APPLIED))
1091 {
1092 if (op->container)
1093 {
1094 if (op->container != sack)
1095 {
1096 tmp = op->container;
1097 apply_container (op, tmp);
1098 sprintf (buf, "You close %s and open ", query_name (tmp));
1099 op->container = sack;
1100 strcat (buf, query_name (sack));
1101 strcat (buf, ".");
1102 }
1103 else
1104 {
1105 CLEAR_FLAG (sack, FLAG_APPLIED);
1106 op->container = NULL;
1107 sprintf (buf, "You close %s.", query_name (sack));
1108 }
1109 }
1110 else
1111 {
1221 CLEAR_FLAG (sack, FLAG_APPLIED); 1112 CLEAR_FLAG (sack, FLAG_APPLIED);
1222 sprintf (buf, "You open %s.", query_name(sack)); 1113 sprintf (buf, "You open %s.", query_name (sack));
1223 SET_FLAG (sack, FLAG_APPLIED); 1114 SET_FLAG (sack, FLAG_APPLIED);
1224 op->container = sack; 1115 op->container = sack;
1225 } 1116 }
1226 } else { /* not applied */ 1117 }
1227 if (sack->slaying) { /* it's locked */ 1118 else
1119 { /* not applied */
1120 if (sack->slaying)
1121 { /* it's locked */
1228 tmp = find_key(op, op, sack); 1122 tmp = find_key (op, op, sack);
1229 if (tmp) { 1123 if (tmp)
1124 {
1230 sprintf (buf, "You unlock %s with %s.", query_name(sack), query_name(tmp)); 1125 sprintf (buf, "You unlock %s with %s.", query_name (sack), query_name (tmp));
1231 SET_FLAG (sack, FLAG_APPLIED); 1126 SET_FLAG (sack, FLAG_APPLIED);
1232 if (sack->env == NULL) { /* if it's on ground,open it also */ 1127 if (sack->env == NULL)
1128 { /* if it's on ground,open it also */
1233 new_draw_info (NDI_UNIQUE,0,op, buf); 1129 new_draw_info (NDI_UNIQUE, 0, op, buf);
1234 apply_container (op, sack); 1130 apply_container (op, sack);
1235 return 1; 1131 return 1;
1236 } 1132 }
1237 } else { 1133 }
1134 else
1135 {
1238 sprintf (buf, "You don't have the key to unlock %s.", 1136 sprintf (buf, "You don't have the key to unlock %s.", query_name (sack));
1239 query_name(sack)); 1137 }
1240 } 1138 }
1241 } else { 1139 else
1140 {
1242 sprintf (buf, "You readied %s.", query_name(sack)); 1141 sprintf (buf, "You readied %s.", query_name (sack));
1243 SET_FLAG (sack, FLAG_APPLIED); 1142 SET_FLAG (sack, FLAG_APPLIED);
1244 if (sack->env == NULL) { /* if it's on ground,open it also */ 1143 if (sack->env == NULL)
1144 { /* if it's on ground,open it also */
1245 new_draw_info (NDI_UNIQUE, 0, op, buf); 1145 new_draw_info (NDI_UNIQUE, 0, op, buf);
1246 apply_container (op, sack); 1146 apply_container (op, sack);
1247 return 1; 1147 return 1;
1148 }
1149 }
1248 } 1150 }
1249 }
1250 }
1251 new_draw_info (NDI_UNIQUE, 0, op, buf); 1151 new_draw_info (NDI_UNIQUE, 0, op, buf);
1152 if (op->contr)
1252 if (op->contr) op->contr->socket.update_look=1; 1153 op->contr->socket.update_look = 1;
1253 return 1; 1154 return 1;
1254} 1155}
1255 1156
1256/** 1157/**
1257 * Eneq(@csd.uu.se): Handle apply on containers. This is for containers 1158 * Eneq(@csd.uu.se): Handle apply on containers. This is for containers
1258 * the player has in their inventory, eg, sacks, luggages, etc. 1159 * the player has in their inventory, eg, sacks, luggages, etc.
1265 * Reminder - there are three states for any container - closed (non applied), 1166 * Reminder - there are three states for any container - closed (non applied),
1266 * applied (not open, but objects that match get tossed into it), and open 1167 * applied (not open, but objects that match get tossed into it), and open
1267 * (applied flag set, and op->container points to the open container) 1168 * (applied flag set, and op->container points to the open container)
1268 */ 1169 */
1269 1170
1171int
1270int esrv_apply_container (object *op, object *sack) 1172esrv_apply_container (object *op, object *sack)
1271{ 1173{
1272 object *tmp=op->container; 1174 object *tmp = op->container;
1175
1273 if(op->type!=PLAYER) 1176 if (op->type != PLAYER)
1274 return 0; /* This might change */ 1177 return 0; /* This might change */
1275 1178
1276 if (sack==NULL || sack->type != CONTAINER) { 1179 if (sack == NULL || sack->type != CONTAINER)
1277 LOG (llevError,
1278 "esrv_apply_container: %s is not container!\n",sack?sack->name:"NULL");
1279 return 0;
1280 } 1180 {
1181 LOG (llevError, "esrv_apply_container: %s is not container!\n", &sack->name);
1182 return 0;
1183 }
1281 1184
1282 /* If we have a currently open container, then it needs to be closed in all cases 1185 /* If we have a currently open container, then it needs to be closed in all cases
1283 * if we are opening this one up. We then fall through if appropriate for 1186 * if we are opening this one up. We then fall through if appropriate for
1284 * openening the new container. 1187 * openening the new container.
1285 */ 1188 */
1286 1189
1287 if (op->container && QUERY_FLAG(sack, FLAG_APPLIED)) { 1190 if (op->container && QUERY_FLAG (sack, FLAG_APPLIED))
1288 if (op->container->env != op) { /* if container is on the ground */ 1191 {
1192 if (op->container->env != op)
1193 { /* if container is on the ground */
1289 op->container->move_off = 0; 1194 op->container->move_off = 0;
1290 } 1195 }
1291 /* Lauwenmark: Handle for plugin close event */ 1196
1292 if (execute_event(tmp, EVENT_CLOSE,op,NULL,NULL,SCRIPT_FIX_ALL)!=0) 1197 if (INVOKE_OBJECT (CLOSE, tmp, ARG_OBJECT (op)))
1293 return 1; 1198 return 1;
1294 1199
1295 new_draw_info_format(NDI_UNIQUE, 0, op, "You close %s.", 1200 new_draw_info_format (NDI_UNIQUE, 0, op, "You close %s.", query_name (op->container));
1296 query_name(op->container));
1297 CLEAR_FLAG(op->container, FLAG_APPLIED); 1201 CLEAR_FLAG (op->container, FLAG_APPLIED);
1298 op->container=NULL; 1202 op->container = NULL;
1299 esrv_update_item (UPD_FLAGS, op, tmp); 1203 esrv_update_item (UPD_FLAGS, op, tmp);
1300 if (tmp == sack) return 1; 1204 if (tmp == sack)
1205 return 1;
1301 } 1206 }
1302 1207
1303 1208
1304 /* If the player is trying to open it (which he must be doing if we got here), 1209 /* If the player is trying to open it (which he must be doing if we got here),
1305 * and it is locked, check to see if player has the equipment to open it. 1210 * and it is locked, check to see if player has the equipment to open it.
1306 */ 1211 */
1307 1212
1308 if (sack->slaying) { /* it's locked */ 1213 if (sack->slaying)
1214 { /* it's locked */
1309 tmp=find_key(op, op, sack); 1215 tmp = find_key (op, op, sack);
1310 if (tmp) { 1216 if (tmp)
1217 {
1311 new_draw_info_format(NDI_UNIQUE, 0, op, "You unlock %s with %s.", query_name(sack), query_name(tmp)); 1218 new_draw_info_format (NDI_UNIQUE, 0, op, "You unlock %s with %s.", query_name (sack), query_name (tmp));
1312 } else {
1313 new_draw_info_format(NDI_UNIQUE, 0, op, "You don't have the key to unlock %s.",
1314 query_name(sack));
1315 return 0;
1316 } 1219 }
1220 else
1221 {
1222 new_draw_info_format (NDI_UNIQUE, 0, op, "You don't have the key to unlock %s.", query_name (sack));
1223 return 0;
1224 }
1317 } 1225 }
1318 1226
1319 /* By the time we get here, we have made sure any other container has been closed and 1227 /* By the time we get here, we have made sure any other container has been closed and
1320 * if this is a locked container, the player they key to open it. 1228 * if this is a locked container, the player they key to open it.
1321 */ 1229 */
1322 1230
1323 /* There are really two cases - the sack is either on the ground, or the sack is 1231 /* There are really two cases - the sack is either on the ground, or the sack is
1324 * part of the players inventory. If on the ground, we assume that the player is 1232 * part of the players inventory. If on the ground, we assume that the player is
1325 * opening it, since if it was being closed, that would have been taken care of above. 1233 * opening it, since if it was being closed, that would have been taken care of above.
1326 */ 1234 */
1327 1235
1328 1236
1329 if (sack->env != op) { 1237 if (sack->env != op)
1238 {
1330 /* Hypothetical case - the player is trying to open a sack that belong to someone 1239 /* Hypothetical case - the player is trying to open a sack that belong to someone
1331 * else. This normally should not happen, but a misbehaving client/player could 1240 * else. This normally should not happen, but a misbehaving client/player could
1332 * try to do it, so lets handle it gracefully. 1241 * try to do it, so lets handle it gracefully.
1333 */ 1242 */
1334 if (sack->env) { 1243 if (sack->env)
1244 {
1335 new_draw_info_format(NDI_UNIQUE, 0, op, "You can't open %s", 1245 new_draw_info_format (NDI_UNIQUE, 0, op, "You can't open %s", query_name (sack));
1336 query_name(sack));
1337 return 0; 1246 return 0;
1338 } 1247 }
1339 /* set these so when the player walks off, we can unapply the sack */ 1248 /* set these so when the player walks off, we can unapply the sack */
1340 sack->move_off = MOVE_ALL; /* trying force closing it */ 1249 sack->move_off = MOVE_ALL; /* trying force closing it */
1341 1250
1342 CLEAR_FLAG (sack, FLAG_APPLIED);
1343 new_draw_info_format(NDI_UNIQUE, 0, op, "You open %s.", query_name(sack));
1344 SET_FLAG (sack, FLAG_APPLIED);
1345 op->container = sack;
1346 esrv_update_item (UPD_FLAGS, op, sack);
1347 esrv_send_inventory (op, sack);
1348
1349 } else { /* sack is in players inventory */
1350 if (QUERY_FLAG (sack, FLAG_APPLIED)) { /* readied sack becoming open */
1351 CLEAR_FLAG (sack, FLAG_APPLIED); 1251 CLEAR_FLAG (sack, FLAG_APPLIED);
1352 new_draw_info_format(NDI_UNIQUE, 0, op, "You open %s.", query_name(sack)); 1252 new_draw_info_format (NDI_UNIQUE, 0, op, "You open %s.", query_name (sack));
1353 SET_FLAG (sack, FLAG_APPLIED); 1253 SET_FLAG (sack, FLAG_APPLIED);
1354 op->container = sack; 1254 op->container = sack;
1355 esrv_update_item (UPD_FLAGS, op, sack); 1255 esrv_update_item (UPD_FLAGS, op, sack);
1356 esrv_send_inventory (op, sack); 1256 esrv_send_inventory (op, sack);
1357 } 1257
1358 else { 1258 }
1259 else
1260 { /* sack is in players inventory */
1261 if (QUERY_FLAG (sack, FLAG_APPLIED))
1262 { /* readied sack becoming open */
1359 CLEAR_FLAG (sack, FLAG_APPLIED); 1263 CLEAR_FLAG (sack, FLAG_APPLIED);
1264 new_draw_info_format (NDI_UNIQUE, 0, op, "You open %s.", query_name (sack));
1265 SET_FLAG (sack, FLAG_APPLIED);
1266 op->container = sack;
1267 esrv_update_item (UPD_FLAGS, op, sack);
1268 esrv_send_inventory (op, sack);
1269 }
1270 else
1271 {
1272 CLEAR_FLAG (sack, FLAG_APPLIED);
1360 new_draw_info_format(NDI_UNIQUE, 0, op, "You readied %s.", query_name(sack)); 1273 new_draw_info_format (NDI_UNIQUE, 0, op, "You readied %s.", query_name (sack));
1361 SET_FLAG (sack, FLAG_APPLIED); 1274 SET_FLAG (sack, FLAG_APPLIED);
1362 esrv_update_item (UPD_FLAGS, op, sack); 1275 esrv_update_item (UPD_FLAGS, op, sack);
1363 } 1276 }
1364 } 1277 }
1365 return 1; 1278 return 1;
1366} 1279}
1367 1280
1368 1281
1369/** 1282/**
1370 * Handles dropping things on altar. 1283 * Handles dropping things on altar.
1371 * Returns true if sacrifice was accepted. 1284 * Returns true if sacrifice was accepted.
1372 */ 1285 */
1286static int
1373static int apply_altar (object *altar, object *sacrifice, object *originator) 1287apply_altar (object *altar, object *sacrifice, object *originator)
1374{ 1288{
1375 /* Only players can make sacrifices on spell casting altars. */ 1289 /* Only players can make sacrifices on spell casting altars. */
1376 if (altar->inv && ( ! originator || originator->type != PLAYER)) 1290 if (altar->inv && (!originator || originator->type != PLAYER))
1377 return 0; 1291 return 0;
1378 1292
1379 if (operate_altar (altar, &sacrifice)) { 1293 if (operate_altar (altar, &sacrifice))
1294 {
1380 /* Simple check. Unfortunately, it means you can't cast magic bullet 1295 /* Simple check. Unfortunately, it means you can't cast magic bullet
1381 * with an altar. We call it a Potion - altars are stationary - it 1296 * with an altar. We call it a Potion - altars are stationary - it
1382 * is up to map designers to use them properly. 1297 * is up to map designers to use them properly.
1383 */ 1298 */
1384 if (altar->inv && altar->inv->type==SPELL) { 1299 if (altar->inv && altar->inv->type == SPELL)
1300 {
1385 new_draw_info_format (NDI_BLACK, 0, originator, "The altar casts %s.", 1301 new_draw_info_format (NDI_BLACK, 0, originator, "The altar casts %s.", &altar->inv->name);
1386 altar->inv->name);
1387 cast_spell (originator, altar, 0, altar->inv, NULL); 1302 cast_spell (originator, altar, 0, altar->inv, NULL);
1388 /* If it is connected, push the button. Fixes some problems with 1303 /* If it is connected, push the button. Fixes some problems with
1389 * old maps. 1304 * old maps.
1390 */ 1305 */
1306
1391/* push_button (altar);*/ 1307/* push_button (altar);*/
1392 } else { 1308 }
1309 else
1310 {
1393 altar->value = 1; /* works only once */ 1311 altar->value = 1; /* works only once */
1394 push_button (altar); 1312 push_button (altar);
1395 } 1313 }
1396 return sacrifice == NULL; 1314
1397 } else { 1315 return !sacrifice;
1316 }
1317 else
1398 return 0; 1318 return 0;
1399 }
1400} 1319}
1401
1402 1320
1403/** 1321/**
1404 * Handles 'movement' of shop mats. 1322 * Handles 'movement' of shop mats.
1405 * Returns 1 if 'op' was destroyed, 0 if not. 1323 * Returns 1 if 'op' was destroyed, 0 if not.
1406 * Largely re-written to not use nearly as many gotos, plus 1324 * Largely re-written to not use nearly as many gotos, plus
1407 * some of this code just looked plain out of date. 1325 * some of this code just looked plain out of date.
1408 * MSW 2001-08-29 1326 * MSW 2001-08-29
1409 */ 1327 */
1328int
1410int apply_shop_mat (object *shop_mat, object *op) 1329apply_shop_mat (object *shop_mat, object *op)
1411{ 1330{
1412 int rv = 0; 1331 int rv = 0;
1413 double opinion; 1332 double opinion;
1414 object *tmp, *next; 1333 object *tmp, *next;
1415 1334
1416 SET_FLAG (op,FLAG_NO_APPLY); /* prevent loops */ 1335 SET_FLAG (op, FLAG_NO_APPLY); /* prevent loops */
1417 1336
1418 if (op->type != PLAYER) { 1337 if (op->type != PLAYER)
1338 {
1419 /* Remove all the unpaid objects that may be carried here. 1339 /* Remove all the unpaid objects that may be carried here.
1420 * This could be pets or monsters that are somehow in 1340 * This could be pets or monsters that are somehow in
1421 * the shop. 1341 * the shop.
1422 */ 1342 */
1423 for (tmp=op->inv; tmp; tmp=next) { 1343 for (tmp = op->inv; tmp; tmp = next)
1344 {
1424 next = tmp->below; 1345 next = tmp->below;
1346
1425 if (QUERY_FLAG(tmp, FLAG_UNPAID)) { 1347 if (QUERY_FLAG (tmp, FLAG_UNPAID))
1348 {
1426 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); 1349 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9);
1427 1350
1428 remove_ob(tmp); 1351 remove_ob (tmp);
1429 if (i==-1) i=0; 1352
1430 tmp->map = op->map; 1353 if (i == -1)
1354 i = 0;
1355
1356 tmp->map = op->map;
1431 tmp->x = op->x + freearr_x[i]; 1357 tmp->x = op->x + freearr_x[i];
1432 tmp->y = op->y + freearr_y[i]; 1358 tmp->y = op->y + freearr_y[i];
1433 insert_ob_in_map(tmp, op->map, op, 0); 1359 insert_ob_in_map (tmp, op->map, op, 0);
1434 } 1360 }
1435 } 1361 }
1436 1362
1437 /* Don't teleport things like spell effects */ 1363 /* Don't teleport things like spell effects */
1438 if (QUERY_FLAG(op, FLAG_NO_PICK)) return 0; 1364 if (QUERY_FLAG (op, FLAG_NO_PICK))
1365 return 0;
1439 1366
1440 /* unpaid objects, or non living objects, can't transfer by 1367 /* unpaid objects, or non living objects, can't transfer by
1441 * shop mats. Instead, put it on a nearby space. 1368 * shop mats. Instead, put it on a nearby space.
1442 */ 1369 */
1443 if (QUERY_FLAG(op, FLAG_UNPAID) || !QUERY_FLAG(op, FLAG_ALIVE)) { 1370 if (QUERY_FLAG (op, FLAG_UNPAID) || !QUERY_FLAG (op, FLAG_ALIVE))
1371 {
1444 1372
1445 /* Somebody dropped an unpaid item, just move to an adjacent place. */ 1373 /* Somebody dropped an unpaid item, just move to an adjacent place. */
1374 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
1375
1376 if (i != -1)
1377 rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat);
1378
1379 return 0;
1380 }
1381 /* Removed code that checked for multipart objects - it appears that
1382 * the teleport function should be able to handle this just fine.
1383 */
1384 rv = teleport (shop_mat, SHOP_MAT, op);
1385 }
1386 else if (can_pay (op) && get_payment (op))
1387 {
1388 /* this is only used for players */
1389 rv = teleport (shop_mat, SHOP_MAT, op);
1390
1391 if (shop_mat->msg)
1392 new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg);
1393 /* This check below is a bit simplistic - generally it should be correct,
1394 * but there is never a guarantee that the bottom space on the map is
1395 * actually the shop floor.
1396 */
1397 else if (!rv && !is_in_shop (op))
1398 {
1399 opinion = shopkeeper_approval (op->map, op);
1400
1401 if (opinion > 0.9)
1402 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper gives you a friendly wave.");
1403 else if (opinion > 0.75)
1404 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper waves to you.");
1405 else if (opinion > 0.5)
1406 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper ignores you.");
1407 else
1408 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper glares at you with contempt.");
1409 }
1410 }
1411 else
1412 {
1413 /* if we get here, a player tried to leave a shop but was not able
1414 * to afford the items he has. We try to move the player so that
1415 * they are not on the mat anymore
1416 */
1446 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); 1417 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
1418
1447 if (i != -1) { 1419 if (i == -1)
1448 rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, 1420 {
1449 shop_mat);
1450 }
1451 return 0;
1452 }
1453 /* Removed code that checked for multipart objects - it appears that
1454 * the teleport function should be able to handle this just fine.
1455 */
1456 rv = teleport (shop_mat, SHOP_MAT, op);
1457 }
1458 /* immediate block below is only used for players */
1459 else if (can_pay(op)) {
1460 get_payment (op, op->inv);
1461 rv = teleport (shop_mat, SHOP_MAT, op);
1462 if (shop_mat->msg) {
1463 new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg);
1464 }
1465 /* This check below is a bit simplistic - generally it should be correct,
1466 * but there is never a guarantee that the bottom space on the map is
1467 * actually the shop floor.
1468 */
1469 else if ( ! rv && (tmp = get_map_ob (op->map, op->x, op->y)) != NULL
1470 && tmp->type != SHOP_FLOOR) {
1471 opinion = shopkeeper_approval(op->map, op);
1472 if ( opinion > 0.9)
1473 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper gives you a friendly wave.");
1474 else if ( opinion > 0.75)
1475 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper waves to you.");
1476 else if ( opinion > 0.5)
1477 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper ignores you.");
1478 else
1479 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper glares at you with contempt.");
1480 }
1481 }
1482 else {
1483 /* if we get here, a player tried to leave a shop but was not able
1484 * to afford the items he has. We try to move the player so that
1485 * they are not on the mat anymore
1486 */
1487
1488 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
1489 if(i == -1) {
1490 LOG (llevError, "Internal shop-mat problem.\n"); 1421 LOG (llevError, "Internal shop-mat problem.\n");
1491 } else { 1422 }
1423 else
1424 {
1492 remove_ob (op); 1425 remove_ob (op);
1493 op->x += freearr_x[i]; 1426 op->x += freearr_x[i];
1494 op->y += freearr_y[i]; 1427 op->y += freearr_y[i];
1495 rv = insert_ob_in_map (op, op->map, shop_mat,0) == NULL; 1428 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL;
1496 esrv_map_scroll(&op->contr->socket, freearr_x[i],freearr_y[i]); 1429 }
1497 op->contr->socket.update_look=1;
1498 op->contr->socket.look_position=0;
1499 }
1500 } 1430 }
1431
1501 CLEAR_FLAG (op, FLAG_NO_APPLY); 1432 CLEAR_FLAG (op, FLAG_NO_APPLY);
1502 return rv; 1433 return rv;
1503} 1434}
1504 1435
1505/** 1436/**
1506 * Handles applying a sign. 1437 * Handles applying a sign.
1507 */ 1438 */
1439static void
1508static void apply_sign (object *op, object *sign, int autoapply) 1440apply_sign (object *op, object *sign, int autoapply)
1509{ 1441{
1510 readable_message_type* msgType; 1442 readable_message_type *msgType;
1511 char newbuf[HUGE_BUF]; 1443 char newbuf[HUGE_BUF];
1444
1512 if (sign->msg == NULL) { 1445 if (sign->msg == NULL)
1446 {
1513 new_draw_info (NDI_UNIQUE, 0, op, "Nothing is written on it."); 1447 new_draw_info (NDI_UNIQUE, 0, op, "Nothing is written on it.");
1448 return;
1449 }
1450
1451 if (sign->stats.food)
1452 {
1453 if (sign->last_eat >= sign->stats.food)
1454 {
1455 if (!sign->move_on)
1456 new_draw_info (NDI_UNIQUE, 0, op, "You cannot read it anymore.");
1514 return; 1457 return;
1515 } 1458 }
1516 1459
1517 if (sign->stats.food) {
1518 if (sign->last_eat >= sign->stats.food) {
1519 if (!sign->move_on)
1520 new_draw_info (NDI_UNIQUE, 0, op, "You cannot read it anymore.");
1521 return;
1522 }
1523
1524 if (!QUERY_FLAG(op, FLAG_WIZPASS)) 1460 if (!QUERY_FLAG (op, FLAG_WIZPASS))
1525 sign->last_eat++; 1461 sign->last_eat++;
1526 } 1462 }
1527 1463
1528 /* Sign or magic mouth? Do we need to see it, or does it talk to us? 1464 /* Sign or magic mouth? Do we need to see it, or does it talk to us?
1529 * No way to know for sure. The presumption is basically that if 1465 * No way to know for sure. The presumption is basically that if
1530 * move_on is zero, it needs to be manually applied (doesn't talk 1466 * move_on is zero, it needs to be manually applied (doesn't talk
1531 * to us). 1467 * to us).
1532 */ 1468 */
1533 if (QUERY_FLAG (op, FLAG_BLIND) && ! QUERY_FLAG (op, FLAG_WIZ) && !sign->move_on) { 1469 if (QUERY_FLAG (op, FLAG_BLIND) && !QUERY_FLAG (op, FLAG_WIZ) && !sign->move_on)
1534 new_draw_info (NDI_UNIQUE, 0, op, 1470 {
1535 "You are unable to read while blind."); 1471 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to read while blind.");
1536 return; 1472 return;
1537 } 1473 }
1538 msgType=get_readable_message_type(sign); 1474 msgType = get_readable_message_type (sign);
1539 snprintf(newbuf,sizeof(newbuf),"%hhu %s", autoapply?1:0,sign->msg); 1475 snprintf (newbuf, sizeof (newbuf), "%hhu %s", autoapply ? 1 : 0, &sign->msg);
1540 draw_ext_info(NDI_UNIQUE | NDI_NAVY, 0, op, msgType->message_type, msgType->message_subtype, newbuf, sign->msg); 1476 draw_ext_info (NDI_UNIQUE | NDI_NAVY, 0, op, msgType->message_type, msgType->message_subtype, newbuf, &sign->msg);
1541} 1477}
1542
1543 1478
1544/** 1479/**
1545 * 'victim' moves onto 'trap' 1480 * 'victim' moves onto 'trap'
1546 * 'victim' leaves 'trap' 1481 * 'victim' leaves 'trap'
1547 * effect is determined by move_on/move_off of trap and move_type of victime. 1482 * effect is determined by move_on/move_off of trap and move_type of victime.
1548 * 1483 *
1549 * originator: Player, monster or other object that caused 'victim' to move 1484 * originator: Player, monster or other object that caused 'victim' to move
1550 * onto 'trap'. Will receive messages caused by this action. May be NULL. 1485 * onto 'trap'. Will receive messages caused by this action. May be NULL.
1551 * However, some types of traps require an originator to function. 1486 * However, some types of traps require an originator to function.
1552 */ 1487 */
1488void
1553void move_apply (object *trap, object *victim, object *originator) 1489move_apply (object *trap, object *victim, object *originator)
1554{ 1490{
1555 static int recursion_depth = 0; 1491 static int recursion_depth = 0;
1556 1492
1557 /* Only exits affect DMs. */ 1493 /* Only exits affect DMs. */
1558 if (QUERY_FLAG(victim, FLAG_WIZPASS) && trap->type != EXIT && trap->type != SIGN) 1494 if (QUERY_FLAG (victim, FLAG_WIZPASS) && trap->type != EXIT && trap->type != SIGN)
1559 return; 1495 return;
1560 1496
1561 /* move_apply() is the most likely candidate for causing unwanted and 1497 /* move_apply() is the most likely candidate for causing unwanted and
1562 * possibly unlimited recursion. 1498 * possibly unlimited recursion.
1563 */ 1499 */
1565 * maps to fail. 1) it's not an error to recurse: 1501 * maps to fail. 1) it's not an error to recurse:
1566 * rune detonates, summoning monster. monster lands on nearby rune. 1502 * rune detonates, summoning monster. monster lands on nearby rune.
1567 * nearby rune detonates. This sort of recursion is expected and 1503 * nearby rune detonates. This sort of recursion is expected and
1568 * proper. This code was causing needless crashes. 1504 * proper. This code was causing needless crashes.
1569 */ 1505 */
1570 if (recursion_depth >= 500) { 1506 if (recursion_depth >= 500)
1507 {
1571 LOG (llevDebug, "WARNING: move_apply(): aborting recursion " 1508 LOG (llevDebug, "WARNING: move_apply(): aborting recursion "
1572 "[trap arch %s, name %s; victim arch %s, name %s]\n", 1509 "[trap arch %s, name %s; victim arch %s, name %s]\n", &trap->arch->name, &trap->name, &victim->arch->name, &victim->name);
1573 trap->arch->name, trap->name, victim->arch->name, victim->name); 1510 return;
1574 return;
1575 } 1511 }
1576 recursion_depth++; 1512 recursion_depth++;
1577 if (trap->head) trap=trap->head; 1513 if (trap->head)
1514 trap = trap->head;
1578 1515
1579 /* Lauwenmark: Handle for plugin trigger event */ 1516 if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator)))
1580 if (execute_event(trap, EVENT_TRIGGER,originator,victim,NULL,SCRIPT_FIX_ALL)!=0) 1517 goto leave;
1518
1519 switch (trap->type)
1520 {
1521 case PLAYERMOVER:
1522 if (trap->attacktype && (trap->level || victim->type != PLAYER) && !should_director_abort (trap, victim))
1523 {
1524 if (!trap->stats.maxsp)
1525 trap->stats.maxsp = 2;
1526
1527 /* Is this correct? From the docs, it doesn't look like it
1528 * should be divided by trap->speed
1529 */
1530 victim->speed_left = -FABS (trap->stats.maxsp * victim->speed / trap->speed);
1531
1532 /* Just put in some sanity check. I think there is a bug in the
1533 * above with some objects have zero speed, and thus the player
1534 * getting permanently paralyzed.
1535 */
1536 if (victim->speed_left < -50.0)
1537 victim->speed_left = -50.0;
1538 /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left); */
1539 }
1581 goto leave; 1540 goto leave;
1582 1541
1583 switch (trap->type) {
1584 case PLAYERMOVER:
1585 if (trap->attacktype && (trap->level || victim->type!=PLAYER) &&
1586 !should_director_abort(trap, victim)) {
1587 if (!trap->stats.maxsp) trap->stats.maxsp=2;
1588
1589 /* Is this correct? From the docs, it doesn't look like it
1590 * should be divided by trap->speed
1591 */
1592 victim->speed_left = -FABS(trap->stats.maxsp*victim->speed/trap->speed);
1593
1594 /* Just put in some sanity check. I think there is a bug in the
1595 * above with some objects have zero speed, and thus the player
1596 * getting permanently paralyzed.
1597 */
1598 if (victim->speed_left<-50.0) victim->speed_left=-50.0;
1599 /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left);*/
1600 }
1601 goto leave;
1602
1603 case SPINNER: 1542 case SPINNER:
1604 if(victim->direction) { 1543 if (victim->direction)
1544 {
1605 victim->direction=absdir(victim->direction-trap->stats.sp); 1545 victim->direction = absdir (victim->direction - trap->stats.sp);
1606 update_turn_face(victim); 1546 update_turn_face (victim);
1607 } 1547 }
1608 goto leave; 1548 goto leave;
1609 1549
1610 case DIRECTOR: 1550 case DIRECTOR:
1611 if(victim->direction && !should_director_abort(trap, victim)) { 1551 if (victim->direction && !should_director_abort (trap, victim))
1552 {
1612 victim->direction=trap->stats.sp; 1553 victim->direction = trap->stats.sp;
1613 update_turn_face(victim); 1554 update_turn_face (victim);
1614 } 1555 }
1615 goto leave; 1556 goto leave;
1616 1557
1617 case BUTTON: 1558 case BUTTON:
1618 case PEDESTAL: 1559 case PEDESTAL:
1619 update_button(trap); 1560 update_button (trap);
1620 goto leave; 1561 goto leave;
1621 1562
1622 case ALTAR: 1563 case ALTAR:
1623 /* sacrifice victim on trap */ 1564 /* sacrifice victim on trap */
1624 apply_altar (trap, victim, originator); 1565 apply_altar (trap, victim, originator);
1625 goto leave; 1566 goto leave;
1626 1567
1627 case THROWN_OBJ: 1568 case THROWN_OBJ:
1628 if (trap->inv == NULL) 1569 if (trap->inv == NULL)
1629 goto leave; 1570 goto leave;
1630 /* fallthrough */ 1571 /* fallthrough */
1631 1572
1632 case ARROW: 1573 case ARROW:
1633
1634 /* bad bug: monster throw a object, make a step forwards, step on object , 1574 /* bad bug: monster throw a object, make a step forwards, step on object ,
1635 * trigger this here and get hit by own missile - and will be own enemy. 1575 * trigger this here and get hit by own missile - and will be own enemy.
1636 * Victim then is his own enemy and will start to kill herself (this is 1576 * Victim then is his own enemy and will start to kill herself (this is
1637 * removed) but we have not synced victim and his missile. To avoid senseless 1577 * removed) but we have not synced victim and his missile. To avoid senseless
1638 * action, we avoid hits here 1578 * action, we avoid hits here
1639 */ 1579 */
1640 if ((QUERY_FLAG (victim, FLAG_ALIVE) && trap->speed) && trap->owner != victim) 1580 if ((QUERY_FLAG (victim, FLAG_ALIVE) && trap->speed) && trap->owner != victim)
1641 hit_with_arrow (trap, victim); 1581 hit_with_arrow (trap, victim);
1642 goto leave; 1582 goto leave;
1643 1583
1644 case SPELL_EFFECT: 1584 case SPELL_EFFECT:
1645 apply_spell_effect(trap, victim); 1585 apply_spell_effect (trap, victim);
1646 goto leave; 1586 goto leave;
1647 1587
1648 case TRAPDOOR: 1588 case TRAPDOOR:
1649 { 1589 {
1650 int max, sound_was_played; 1590 int max, sound_was_played;
1651 object *ab, *ab_next; 1591 object *ab, *ab_next;
1592
1652 if(!trap->value) { 1593 if (!trap->value)
1653 int tot; 1594 {
1595 int tot;
1596
1654 for(ab=trap->above,tot=0;ab!=NULL;ab=ab->above) 1597 for (ab = trap->above, tot = 0; ab != NULL; ab = ab->above)
1655 if ((ab->move_type && trap->move_on) || ab->move_type==0) 1598 if ((ab->move_type && trap->move_on) || ab->move_type == 0)
1656 tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying; 1599 tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying;
1657 1600
1658 if(!(trap->value=(tot>trap->weight)?1:0)) 1601 if (!(trap->value = (tot > trap->weight) ? 1 : 0))
1659 goto leave; 1602 goto leave;
1660 1603
1661 SET_ANIMATION(trap, trap->value); 1604 SET_ANIMATION (trap, trap->value);
1662 update_object(trap,UP_OBJ_FACE); 1605 update_object (trap, UP_OBJ_FACE);
1663 } 1606 }
1664 1607
1665 for (ab = trap->above, max=100, sound_was_played = 0; --max && ab; ab=ab_next) { 1608 for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab; ab = ab_next)
1609 {
1666 /* need to set this up, since if we do transfer the object, 1610 /* need to set this up, since if we do transfer the object,
1667 * ab->above would be bogus 1611 * ab->above would be bogus
1668 */ 1612 */
1669 ab_next = ab->above; 1613 ab_next = ab->above;
1670 1614
1671 if ((ab->move_type && trap->move_on) || ab->move_type==0) { 1615 if ((ab->move_type && trap->move_on) || ab->move_type == 0)
1672 if ( ! sound_was_played) { 1616 {
1617 if (!sound_was_played)
1618 {
1673 play_sound_map(trap->map, trap->x, trap->y, SOUND_FALL_HOLE); 1619 play_sound_map (trap->map, trap->x, trap->y, SOUND_FALL_HOLE);
1674 sound_was_played = 1; 1620 sound_was_played = 1;
1675 } 1621 }
1676 new_draw_info(NDI_UNIQUE, 0,ab,"You fall into a trapdoor!"); 1622 new_draw_info (NDI_UNIQUE, 0, ab, "You fall into a trapdoor!");
1677 transfer_ob(ab,(int)EXIT_X(trap),(int)EXIT_Y(trap),0,ab); 1623 transfer_ob (ab, (int) EXIT_X (trap), (int) EXIT_Y (trap), 0, ab);
1678 } 1624 }
1679 } 1625 }
1680 goto leave; 1626 goto leave;
1681 } 1627 }
1682 1628
1683 1629
1684 case CONVERTER: 1630 case CONVERTER:
1685 if (convert_item (victim, trap) < 0) { 1631 if (convert_item (victim, trap) < 0)
1686 object *op; 1632 {
1633 object *op;
1687 1634
1688 new_draw_info_format(NDI_UNIQUE, 0, originator, "The %s seems to be broken!", query_name(trap)); 1635 new_draw_info_format (NDI_UNIQUE, 0, originator, "The %s seems to be broken!", query_name (trap));
1689 1636
1690 op = get_archetype("burnout"); 1637 op = get_archetype ("burnout");
1691 if (op != NULL) { 1638 if (op != NULL)
1692 op->x = trap->x; 1639 {
1693 op->y = trap->y; 1640 op->x = trap->x;
1641 op->y = trap->y;
1694 insert_ob_in_map(op, trap->map, trap, 0); 1642 insert_ob_in_map (op, trap->map, trap, 0);
1695 } 1643 }
1696 } 1644 }
1697 goto leave; 1645 goto leave;
1698 1646
1699 case TRIGGER_BUTTON: 1647 case TRIGGER_BUTTON:
1700 case TRIGGER_PEDESTAL: 1648 case TRIGGER_PEDESTAL:
1701 case TRIGGER_ALTAR: 1649 case TRIGGER_ALTAR:
1702 check_trigger (trap, victim); 1650 check_trigger (trap, victim);
1703 goto leave; 1651 goto leave;
1704 1652
1705 case DEEP_SWAMP: 1653 case DEEP_SWAMP:
1706 walk_on_deep_swamp (trap, victim); 1654 walk_on_deep_swamp (trap, victim);
1707 goto leave; 1655 goto leave;
1708 1656
1709 case CHECK_INV: 1657 case CHECK_INV:
1710 check_inv (victim, trap); 1658 check_inv (victim, trap);
1711 goto leave; 1659 goto leave;
1712 1660
1713 case HOLE: 1661 case HOLE:
1714 /* Hole not open? */ 1662 /* Hole not open? */
1715 if(trap->stats.wc > 0) 1663 if (trap->stats.wc > 0)
1716 goto leave; 1664 goto leave;
1717 1665
1718 /* Is this a multipart monster and not the head? If so, return. 1666 /* Is this a multipart monster and not the head? If so, return.
1719 * Processing will happen if the head runs into the pit 1667 * Processing will happen if the head runs into the pit
1720 */ 1668 */
1721 if (victim->head) 1669 if (victim->head)
1722 goto leave; 1670 goto leave;
1723 1671
1724 play_sound_map (victim->map, victim->x, victim->y, SOUND_FALL_HOLE); 1672 play_sound_map (victim->map, victim->x, victim->y, SOUND_FALL_HOLE);
1725 new_draw_info (NDI_UNIQUE, 0, victim, "You fall through the hole!\n"); 1673 new_draw_info (NDI_UNIQUE, 0, victim, "You fall through the hole!\n");
1726 transfer_ob (victim, EXIT_X (trap), EXIT_Y (trap), 1, victim); 1674 transfer_ob (victim, EXIT_X (trap), EXIT_Y (trap), 1, victim);
1727 goto leave; 1675 goto leave;
1728 1676
1729 case EXIT: 1677 case EXIT:
1730 if (victim->type == PLAYER && EXIT_PATH (trap)) { 1678 if (victim->type == PLAYER && EXIT_PATH (trap))
1679 {
1731 /* Basically, don't show exits leading to random maps the 1680 /* Basically, don't show exits leading to random maps the
1732 * players output. 1681 * players output.
1733 */ 1682 */
1734 if (trap->msg && strncmp(EXIT_PATH(trap),"/!",2) && strncmp(EXIT_PATH(trap), "/random/", 8)) 1683 if (trap->msg && strncmp (EXIT_PATH (trap), "/!", 2) && strncmp (EXIT_PATH (trap), "/random/", 8))
1735 new_draw_info (NDI_NAVY, 0, victim, trap->msg); 1684 new_draw_info (NDI_NAVY, 0, victim, trap->msg);
1736 enter_exit (victim, trap); 1685 enter_exit (victim, trap);
1737 } 1686 }
1738 goto leave; 1687 goto leave;
1739 1688
1740 case ENCOUNTER: 1689 case ENCOUNTER:
1741 /* may be some leftovers on this */ 1690 /* may be some leftovers on this */
1742 goto leave; 1691 goto leave;
1743 1692
1744 case SHOP_MAT: 1693 case SHOP_MAT:
1745 apply_shop_mat (trap, victim); 1694 apply_shop_mat (trap, victim);
1746 goto leave; 1695 goto leave;
1747 1696
1748 /* Drop a certain amount of gold, and have one item identified */ 1697 /* Drop a certain amount of gold, and have one item identified */
1749 case IDENTIFY_ALTAR: 1698 case IDENTIFY_ALTAR:
1750 apply_id_altar (victim, trap, originator); 1699 apply_id_altar (victim, trap, originator);
1751 goto leave; 1700 goto leave;
1752 1701
1753 case SIGN: 1702 case SIGN:
1754 if (victim->type != PLAYER && trap->stats.food > 0) 1703 if (victim->type != PLAYER && trap->stats.food > 0)
1755 goto leave; /* monsters musn't apply magic_mouths with counters */ 1704 goto leave; /* monsters musn't apply magic_mouths with counters */
1756 1705
1757 apply_sign (victim, trap, 1); 1706 apply_sign (victim, trap, 1);
1758 goto leave; 1707 goto leave;
1759 1708
1760 case CONTAINER: 1709 case CONTAINER:
1761 if (victim->type==PLAYER) 1710 if (victim->type == PLAYER)
1762 (void) esrv_apply_container (victim, trap); 1711 (void) esrv_apply_container (victim, trap);
1763 else 1712 else
1764 (void) apply_container (victim, trap); 1713 (void) apply_container (victim, trap);
1765 goto leave; 1714 goto leave;
1766 1715
1767 case RUNE: 1716 case RUNE:
1768 case TRAP: 1717 case TRAP:
1769 if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE)) { 1718 if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE))
1719 {
1770 spring_trap(trap, victim); 1720 spring_trap (trap, victim);
1771 } 1721 }
1772 goto leave; 1722 goto leave;
1773 1723
1774 default: 1724 default:
1775 LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not " 1725 LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not "
1776 "handled in move_apply()\n", trap->name, trap->arch->name, 1726 "handled in move_apply()\n", &trap->name, &trap->arch->name, trap->type);
1777 trap->type);
1778 goto leave; 1727 goto leave;
1779 } 1728 }
1780 1729
1781 leave: 1730leave:
1782 recursion_depth--; 1731 recursion_depth--;
1783} 1732}
1784 1733
1785/** 1734/**
1786 * Handles reading a regular (ie not containing a spell) book. 1735 * Handles reading a regular (ie not containing a spell) book.
1787 */ 1736 */
1737static void
1788static void apply_book (object *op, object *tmp) 1738apply_book (object *op, object *tmp)
1789{ 1739{
1790 int lev_diff; 1740 int lev_diff;
1791 object *skill_ob; 1741 object *skill_ob;
1792 1742
1793 if(QUERY_FLAG(op, FLAG_BLIND)&&!QUERY_FLAG(op,FLAG_WIZ)) { 1743 if (QUERY_FLAG (op, FLAG_BLIND) && !QUERY_FLAG (op, FLAG_WIZ))
1744 {
1794 new_draw_info(NDI_UNIQUE, 0,op,"You are unable to read while blind."); 1745 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to read while blind.");
1795 return; 1746 return;
1796 } 1747 }
1797 if(tmp->msg==NULL) { 1748 if (tmp->msg == NULL)
1798 new_draw_info_format(NDI_UNIQUE, 0, op, 1749 {
1799 "You open the %s and find it empty.", tmp->name); 1750 new_draw_info_format (NDI_UNIQUE, 0, op, "You open the %s and find it empty.", &tmp->name);
1800 return; 1751 return;
1801 } 1752 }
1802 1753
1803 /* need a literacy skill to read stuff! */ 1754 /* need a literacy skill to read stuff! */
1804 skill_ob = find_skill_by_name(op, tmp->skill); 1755 skill_ob = find_skill_by_name (op, tmp->skill);
1805 if ( ! skill_ob) { 1756 if (!skill_ob)
1806 new_draw_info(NDI_UNIQUE, 0,op,
1807 "You are unable to decipher the strange symbols.");
1808 return;
1809 } 1757 {
1758 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to decipher the strange symbols.");
1759 return;
1760 }
1810 lev_diff = tmp->level - (skill_ob->level + 5); 1761 lev_diff = tmp->level - (skill_ob->level + 5);
1811 if ( ! QUERY_FLAG (op, FLAG_WIZ) && lev_diff > 0) { 1762 if (!QUERY_FLAG (op, FLAG_WIZ) && lev_diff > 0)
1763 {
1812 if (lev_diff < 2) 1764 if (lev_diff < 2)
1813 new_draw_info(NDI_UNIQUE, 0,op,"This book is just barely beyond your comprehension."); 1765 new_draw_info (NDI_UNIQUE, 0, op, "This book is just barely beyond your comprehension.");
1814 else if (lev_diff < 3) 1766 else if (lev_diff < 3)
1815 new_draw_info(NDI_UNIQUE, 0,op,"This book is slightly beyond your comprehension."); 1767 new_draw_info (NDI_UNIQUE, 0, op, "This book is slightly beyond your comprehension.");
1816 else if (lev_diff < 5) 1768 else if (lev_diff < 5)
1817 new_draw_info(NDI_UNIQUE, 0,op,"This book is beyond your comprehension."); 1769 new_draw_info (NDI_UNIQUE, 0, op, "This book is beyond your comprehension.");
1818 else if (lev_diff < 8) 1770 else if (lev_diff < 8)
1819 new_draw_info(NDI_UNIQUE, 0,op,"This book is quite a bit beyond your comprehension."); 1771 new_draw_info (NDI_UNIQUE, 0, op, "This book is quite a bit beyond your comprehension.");
1820 else if (lev_diff < 15) 1772 else if (lev_diff < 15)
1821 new_draw_info(NDI_UNIQUE, 0,op,"This book is way beyond your comprehension."); 1773 new_draw_info (NDI_UNIQUE, 0, op, "This book is way beyond your comprehension.");
1822 else 1774 else
1823 new_draw_info(NDI_UNIQUE, 0,op,"This book is totally beyond your comprehension."); 1775 new_draw_info (NDI_UNIQUE, 0, op, "This book is totally beyond your comprehension.");
1824 return; 1776 return;
1825 }
1826
1827
1828 /* Lauwenmark: Handle for plugin book event */
1829 /*printf("Book apply: %s\n", tmp->name);
1830 execute_event(tmp, EVENT_APPLY,op,NULL,SCRIPT_FIX_ALL);
1831 printf("Book applied: %s\n", tmp->name);*/
1832 /*if ((evt = find_event(tmp, EVENT_APPLY)) != NULL)
1833 { 1777 }
1834 CFParm CFP; 1778
1835 int k, l, m;
1836 uint32 n;
1837 new_draw_info_format (NDI_UNIQUE, 0, op,
1838 "You open the %s and start reading.", tmp->name);
1839 k = EVENT_APPLY;
1840 l = SCRIPT_FIX_ALL;
1841 m = 0;
1842 n = 0;
1843 CFP.Value[0] = &k;
1844 CFP.Value[1] = op;
1845 CFP.Value[2] = tmp;
1846 CFP.Value[3] = NULL;
1847 CFP.Value[4] = NULL;
1848 CFP.Value[5] = &n;
1849 CFP.Value[6] = &m;
1850 CFP.Value[7] = &m;
1851 CFP.Value[8] = &l;
1852 CFP.Value[9] = (void*)evt->hook;
1853 CFP.Value[10]= (void*)evt->options;
1854 if (findPlugin(evt->plugin)>=0)
1855 ((PlugList[findPlugin(evt->plugin)].eventfunc) (&CFP));
1856 }
1857 else*/{
1858 readable_message_type* msgType = get_readable_message_type(tmp); 1779 readable_message_type *msgType = get_readable_message_type (tmp);
1780
1859 draw_ext_info_format(NDI_UNIQUE | NDI_NAVY, 0, op, 1781 draw_ext_info_format (NDI_UNIQUE | NDI_NAVY, 0, op,
1860 msgType->message_type, msgType->message_subtype, 1782 msgType->message_type, msgType->message_subtype,
1861 "You open the %s and start reading.\n%s", 1783 "You open the %s and start reading.\n%s", "%s\n%s", long_desc (tmp, op), &tmp->msg);
1862 "%s\n%s",
1863 long_desc(tmp,op), tmp->msg);
1864 }
1865 1784
1866 /* gain xp from reading */ 1785 /* gain xp from reading */
1867 if(!QUERY_FLAG(tmp,FLAG_NO_SKILL_IDENT)) { /* only if not read before */ 1786 if (!QUERY_FLAG (tmp, FLAG_NO_SKILL_IDENT))
1787 { /* only if not read before */
1868 int exp_gain=calc_skill_exp(op,tmp, skill_ob); 1788 int exp_gain = calc_skill_exp (op, tmp, skill_ob);
1789
1869 if(!QUERY_FLAG(tmp,FLAG_IDENTIFIED)) { 1790 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1791 {
1870 /*exp_gain *= 2; because they just identified it too */ 1792 /*exp_gain *= 2; because they just identified it too */
1871 SET_FLAG(tmp,FLAG_IDENTIFIED); 1793 SET_FLAG (tmp, FLAG_IDENTIFIED);
1872 /* If in a container, update how it looks */ 1794 /* If in a container, update how it looks */
1795 if (tmp->env)
1873 if(tmp->env) esrv_update_item(UPD_FLAGS|UPD_NAME, op,tmp); 1796 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1797 else
1874 else op->contr->socket.update_look=1; 1798 op->contr->socket.update_look = 1;
1875 } 1799 }
1876 change_exp(op,exp_gain, skill_ob->skill, 0); 1800 change_exp (op, exp_gain, skill_ob->skill, 0);
1877 SET_FLAG(tmp,FLAG_NO_SKILL_IDENT); /* so no more xp gained from this book */ 1801 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT); /* so no more xp gained from this book */
1878 } 1802 }
1879} 1803}
1880 1804
1881/** 1805/**
1882 * Handles the applying of a skill scroll, calling learn_skill straight. 1806 * Handles the applying of a skill scroll, calling learn_skill straight.
1883 * op is the person learning the skill, tmp is the skill scroll object 1807 * op is the person learning the skill, tmp is the skill scroll object
1884 */ 1808 */
1809static void
1885static void apply_skillscroll (object *op, object *tmp) 1810apply_skillscroll (object *op, object *tmp)
1886{ 1811{
1887 switch ((int) learn_skill (op, tmp)) { 1812 switch ((int) learn_skill (op, tmp))
1888 case 0: 1813 {
1814 case 0:
1889 new_draw_info(NDI_UNIQUE, 0,op,"You already possess the knowledge "); 1815 new_draw_info (NDI_UNIQUE, 0, op, "You already possess the knowledge ");
1890 new_draw_info_format(NDI_UNIQUE, 0,op,"held within the %s.\n",query_name(tmp)); 1816 new_draw_info_format (NDI_UNIQUE, 0, op, "held within the %s.\n", query_name (tmp));
1891 return; 1817 return;
1892 1818
1893 case 1: 1819 case 1:
1894 new_draw_info_format(NDI_UNIQUE, 0,op,"You succeed in learning %s", 1820 new_draw_info_format (NDI_UNIQUE, 0, op, "You succeed in learning %s", &tmp->skill);
1895 tmp->skill);
1896 new_draw_info_format(NDI_UNIQUE, 0, op,
1897 "Type 'bind ready_skill %s",tmp->skill);
1898 new_draw_info(NDI_UNIQUE, 0,op,"to store the skill in a key.");
1899 decrease_ob(tmp); 1821 decrease_ob (tmp);
1900 return; 1822 return;
1901 1823
1902 default: 1824 default:
1903 new_draw_info_format(NDI_UNIQUE,0,op, 1825 new_draw_info_format (NDI_UNIQUE, 0, op, "You fail to learn the knowledge of the %s.\n", query_name (tmp));
1904 "You fail to learn the knowledge of the %s.\n",query_name(tmp));
1905 decrease_ob(tmp); 1826 decrease_ob (tmp);
1906 return; 1827 return;
1907 } 1828 }
1908} 1829}
1909 1830
1910/** 1831/**
1911 * Actually makes op learn spell. 1832 * Actually makes op learn spell.
1912 * Informs player of what happens. 1833 * Informs player of what happens.
1913 */ 1834 */
1835void
1914void do_learn_spell (object *op, object *spell, int special_prayer) 1836do_learn_spell (object *op, object *spell, int special_prayer)
1915{ 1837{
1916 object *tmp; 1838 object *tmp;
1917 1839
1918 if (op->type != PLAYER) { 1840 if (op->type != PLAYER)
1841 {
1919 LOG (llevError, "BUG: do_learn_spell(): not a player\n"); 1842 LOG (llevError, "BUG: do_learn_spell(): not a player\n");
1920 return; 1843 return;
1921 } 1844 }
1922 1845
1923 /* Upgrade special prayers to normal prayers */ 1846 /* Upgrade special prayers to normal prayers */
1924 if ((tmp=check_spell_known (op, spell->name))!=NULL) { 1847 if ((tmp = check_spell_known (op, spell->name)) != NULL)
1848 {
1925 if (special_prayer && !QUERY_FLAG(tmp, FLAG_STARTEQUIP)) { 1849 if (special_prayer && !QUERY_FLAG (tmp, FLAG_STARTEQUIP))
1850 {
1926 LOG (llevError, "BUG: do_learn_spell(): spell already known, but not marked as startequip\n"); 1851 LOG (llevError, "BUG: do_learn_spell(): spell already known, but not marked as startequip\n");
1927 return; 1852 return;
1928 } 1853 }
1929 return; 1854 return;
1930 } 1855 }
1931 1856
1932 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0); 1857 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0);
1933 tmp = get_object(); 1858 tmp = get_object ();
1934 copy_object(spell, tmp); 1859 copy_object (spell, tmp);
1935 insert_ob_in_ob(tmp, op); 1860 insert_ob_in_ob (tmp, op);
1936 1861
1937 if (special_prayer) { 1862 if (special_prayer)
1863 {
1938 SET_FLAG(tmp, FLAG_STARTEQUIP); 1864 SET_FLAG (tmp, FLAG_STARTEQUIP);
1939 } 1865 }
1940 1866
1941 new_draw_info_format (NDI_UNIQUE, 0, op,
1942 "Type 'bind cast %s", spell->name);
1943 new_draw_info (NDI_UNIQUE, 0, op, "to store the spell in a key.");
1944 esrv_add_spells(op->contr, tmp); 1867 esrv_add_spells (op->contr, tmp);
1945} 1868}
1946 1869
1947/** 1870/**
1948 * Erases spell from player's inventory. 1871 * Erases spell from player's inventory.
1949 */ 1872 */
1873void
1950void do_forget_spell (object *op, const char *spell) 1874do_forget_spell (object *op, const char *spell)
1951{ 1875{
1952 object *spob; 1876 object *spob;
1953 1877
1954 if (op->type != PLAYER) { 1878 if (op->type != PLAYER)
1879 {
1955 LOG (llevError, "BUG: do_forget_spell(): not a player\n"); 1880 LOG (llevError, "BUG: do_forget_spell(): not a player\n");
1956 return; 1881 return;
1957 } 1882 }
1958 if ( (spob=check_spell_known (op, spell)) == NULL) { 1883 if ((spob = check_spell_known (op, spell)) == NULL)
1884 {
1959 LOG (llevError, "BUG: do_forget_spell(): spell not known\n"); 1885 LOG (llevError, "BUG: do_forget_spell(): spell not known\n");
1960 return; 1886 return;
1961 }
1962 1887 }
1963 new_draw_info_format (NDI_UNIQUE|NDI_NAVY, 0, op, 1888
1964 "You lose knowledge of %s.", spell); 1889 new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You lose knowledge of %s.", spell);
1965 player_unready_range_ob(op->contr, spob); 1890 player_unready_range_ob (op->contr, spob);
1966 esrv_remove_spell(op->contr, spob); 1891 esrv_remove_spell (op->contr, spob);
1967 remove_ob(spob); 1892 remove_ob (spob);
1968 free_object(spob); 1893 free_object (spob);
1969} 1894}
1970 1895
1971/** 1896/**
1972 * Handles player applying a spellbook. 1897 * Handles player applying a spellbook.
1973 * Checks whether player has knowledge of required skill, doesn't already know the spell, 1898 * Checks whether player has knowledge of required skill, doesn't already know the spell,
1974 * stuff like that. Random learning failure too. 1899 * stuff like that. Random learning failure too.
1975 */ 1900 */
1901static void
1976static void apply_spellbook (object *op, object *tmp) 1902apply_spellbook (object *op, object *tmp)
1977{ 1903{
1978 object *skop, *spell, *spell_skill; 1904 object *skop, *spell, *spell_skill;
1979 1905
1980 if(QUERY_FLAG(op, FLAG_BLIND)&&!QUERY_FLAG(op,FLAG_WIZ)) { 1906 if (QUERY_FLAG (op, FLAG_BLIND) && !QUERY_FLAG (op, FLAG_WIZ))
1907 {
1981 new_draw_info(NDI_UNIQUE, 0,op,"You are unable to read while blind."); 1908 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to read while blind.");
1982 return; 1909 return;
1983 } 1910 }
1984 1911
1985 /* artifact_spellbooks have 'slaying' field point to a spell name, 1912 /* artifact_spellbooks have 'slaying' field point to a spell name,
1986 * instead of having their spell stored in stats.sp. These are 1913 * instead of having their spell stored in stats.sp. These are
1987 * legacy spellbooks 1914 * legacy spellbooks
1988 */ 1915 */
1989 1916
1990 if(tmp->slaying != NULL) { 1917 if (tmp->slaying != NULL)
1918 {
1991 spell=arch_to_object(find_archetype_by_object_name(tmp->slaying)); 1919 spell = arch_to_object (find_archetype_by_object_name (tmp->slaying));
1992 if (!spell) { 1920 if (!spell)
1993 new_draw_info_format(NDI_UNIQUE, 0, op, 1921 {
1994 "The book's formula for %s is incomplete", tmp->slaying); 1922 new_draw_info_format (NDI_UNIQUE, 0, op, "The book's formula for %s is incomplete", &tmp->slaying);
1995 return; 1923 return;
1996 } 1924 }
1997 else 1925 else
1998 insert_ob_in_ob(spell, tmp); 1926 insert_ob_in_ob (spell, tmp);
1999 free_string(tmp->slaying);
2000 tmp->slaying=NULL; 1927 tmp->slaying = NULL;
2001 } 1928 }
2002 1929
2003 skop = find_skill_by_name(op, tmp->skill); 1930 skop = find_skill_by_name (op, tmp->skill);
2004 1931
2005 /* need a literacy skill to learn spells. Also, having a literacy level 1932 /* need a literacy skill to learn spells. Also, having a literacy level
2006 * lower than the spell will make learning the spell more difficult */ 1933 * lower than the spell will make learning the spell more difficult */
2007 if ( !skop) { 1934 if (!skop)
1935 {
2008 new_draw_info(NDI_UNIQUE, 0,op,"You can't read! Your attempt fails."); 1936 new_draw_info (NDI_UNIQUE, 0, op, "You can't read! Your attempt fails.");
2009 return; 1937 return;
2010 } 1938 }
2011 1939
2012 spell = tmp->inv; 1940 spell = tmp->inv;
2013 if (!spell) { 1941 if (!spell)
1942 {
2014 LOG(llevError,"apply_spellbook: Book %s has no spell in it!\n", tmp->name); 1943 LOG (llevError, "apply_spellbook: Book %s has no spell in it!\n", &tmp->name);
2015 new_draw_info(NDI_UNIQUE, 0,op,"The spellbook symbols make no sense."); 1944 new_draw_info (NDI_UNIQUE, 0, op, "The spellbook symbols make no sense.");
2016 return; 1945 return;
2017 } 1946 }
1947
2018 if (spell->level > (skop->level+10)) { 1948 if (spell->level > (skop->level + 10))
1949 {
2019 new_draw_info(NDI_UNIQUE, 0,op,"You are unable to decipher the strange symbols."); 1950 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to decipher the strange symbols.");
2020 return; 1951 return;
2021 } 1952 }
2022 1953
2023 new_draw_info_format(NDI_UNIQUE, 0, op, 1954 new_draw_info_format (NDI_UNIQUE, 0, op, "The spellbook contains the %s level spell %s.", get_levelnumber (spell->level), &spell->name);
2024 "The spellbook contains the %s level spell %s.",
2025 get_levelnumber(spell->level), spell->name);
2026 1955
2027 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED)) { 1956 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1957 {
2028 identify(tmp); 1958 identify (tmp);
2029 if (tmp->env) 1959 if (tmp->env)
2030 esrv_update_item(UPD_FLAGS|UPD_NAME,op,tmp); 1960 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
2031 else 1961 else
2032 op->contr->socket.update_look=1; 1962 op->contr->socket.update_look = 1;
2033 } 1963 }
2034 1964
2035 /* I removed the check for special_prayer_mark here - it didn't make 1965 /* I removed the check for special_prayer_mark here - it didn't make
2036 * a lot of sense - special prayers are not found in spellbooks, and 1966 * a lot of sense - special prayers are not found in spellbooks, and
2037 * if the player doesn't know the spell, doesn't make a lot of sense that 1967 * if the player doesn't know the spell, doesn't make a lot of sense that
2038 * they would have a special prayer mark. 1968 * they would have a special prayer mark.
2039 */ 1969 */
2040 if (check_spell_known (op, spell->name)) { 1970 if (check_spell_known (op, spell->name))
1971 {
2041 new_draw_info(NDI_UNIQUE, 0,op,"You already know that spell.\n"); 1972 new_draw_info (NDI_UNIQUE, 0, op, "You already know that spell.\n");
2042 return; 1973 return;
2043 } 1974 }
2044 1975
2045 if (spell->skill) { 1976 if (spell->skill)
1977 {
2046 spell_skill = find_skill_by_name(op, spell->skill); 1978 spell_skill = find_skill_by_name (op, spell->skill);
1979
2047 if (!spell_skill) { 1980 if (!spell_skill)
2048 new_draw_info_format(NDI_UNIQUE, 0, op, 1981 {
2049 "You lack the skill %s to use this spell", 1982 new_draw_info_format (NDI_UNIQUE, 0, op, "You lack the skill %s to use this spell", &spell->skill);
2050 spell->skill);
2051 return; 1983 return;
2052 } 1984 }
1985
2053 if (spell_skill->level < spell->level) { 1986 if (spell_skill->level < spell->level)
2054 new_draw_info_format(NDI_UNIQUE, 0, op, 1987 {
2055 "You need to be level %d in %s to learn this spell.", 1988 new_draw_info_format (NDI_UNIQUE, 0, op, "You need to be level %d in %s to learn this spell.", spell->level, &spell->skill);
2056 spell->level, spell->skill);
2057 return; 1989 return;
2058 } 1990 }
2059 } 1991 }
2060 1992
2061 /* Logic as follows 1993 /* Logic as follows
2062 * 1994 *
2063 * 1- MU spells use Int to learn, Cleric spells use Wisdom 1995 * 1- MU spells use Int to learn, Cleric spells use Wisdom
2064 * 1996 *
2065 * 2- The learner's skill level in literacy adjusts the chance to learn 1997 * 2- The learner's skill level in literacy adjusts the chance to learn
2066 * a spell. 1998 * a spell.
2067 * 1999 *
2068 * 3 -Automatically fail to learn if you read while confused 2000 * 3 -Automatically fail to learn if you read while confused
2069 * 2001 *
2070 * Overall, chances are the same but a player will find having a high 2002 * Overall, chances are the same but a player will find having a high
2071 * literacy rate very useful! -b.t. 2003 * literacy rate very useful! -b.t.
2072 */ 2004 */
2073 if(QUERY_FLAG(op,FLAG_CONFUSED)) { 2005 if (QUERY_FLAG (op, FLAG_CONFUSED))
2006 {
2074 new_draw_info(NDI_UNIQUE,0,op,"In your confused state you flub the wording of the text!"); 2007 new_draw_info (NDI_UNIQUE, 0, op, "In your confused state you flub the wording of the text!");
2075 scroll_failure(op, 0 - random_roll(0, spell->level, op, PREFER_LOW), MAX(spell->stats.sp, spell->stats.grace)); 2008 scroll_failure (op, 0 - random_roll (0, spell->level, op, PREFER_LOW), MAX (spell->stats.sp, spell->stats.grace));
2009 }
2076 } else if(QUERY_FLAG(tmp,FLAG_STARTEQUIP) || 2010 else if (QUERY_FLAG (tmp, FLAG_STARTEQUIP) ||
2077 (random_roll(0, 100, op, PREFER_LOW)-(5*skop->level)) < 2011 (random_roll (0, 100, op, PREFER_LOW) - (5 * skop->level)) < learn_spell[spell->stats.grace ? op->stats.Wis : op->stats.Int])
2078 learn_spell[spell->stats.grace ? op->stats.Wis : op->stats.Int]) { 2012 {
2079 2013
2080 new_draw_info(NDI_UNIQUE, 0,op,"You succeed in learning the spell!"); 2014 new_draw_info (NDI_UNIQUE, 0, op, "You succeed in learning the spell!");
2081 do_learn_spell (op, spell, 0); 2015 do_learn_spell (op, spell, 0);
2082 2016
2083 /* xp gain to literacy for spell learning */ 2017 /* xp gain to literacy for spell learning */
2084 if ( ! QUERY_FLAG (tmp, FLAG_STARTEQUIP)) 2018 if (!QUERY_FLAG (tmp, FLAG_STARTEQUIP))
2085 change_exp(op,calc_skill_exp(op,tmp,skop), skop->skill, 0); 2019 change_exp (op, calc_skill_exp (op, tmp, skop), skop->skill, 0);
2086 } else { 2020 }
2021 else
2022 {
2087 play_sound_player_only(op->contr, SOUND_FUMBLE_SPELL,0,0); 2023 play_sound_player_only (op->contr, SOUND_FUMBLE_SPELL, 0, 0);
2088 new_draw_info(NDI_UNIQUE, 0,op,"You fail to learn the spell.\n"); 2024 new_draw_info (NDI_UNIQUE, 0, op, "You fail to learn the spell.\n");
2089 } 2025 }
2090 decrease_ob(tmp); 2026 decrease_ob (tmp);
2091} 2027}
2092 2028
2093/** 2029/**
2094 * Handles applying a spell scroll. 2030 * Handles applying a spell scroll.
2095 */ 2031 */
2032void
2096void apply_scroll (object *op, object *tmp, int dir) 2033apply_scroll (object *op, object *tmp, int dir)
2097{ 2034{
2098 object *skop; 2035 object *skop;
2099 2036
2100 if(QUERY_FLAG(op, FLAG_BLIND)&&!QUERY_FLAG(op,FLAG_WIZ)) { 2037 if (QUERY_FLAG (op, FLAG_BLIND) && !QUERY_FLAG (op, FLAG_WIZ))
2038 {
2101 new_draw_info(NDI_UNIQUE, 0,op, "You are unable to read while blind."); 2039 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to read while blind.");
2102 return; 2040 return;
2103 } 2041 }
2104 2042
2105 if (!tmp->inv || tmp->inv->type != SPELL) { 2043 if (!tmp->inv || tmp->inv->type != SPELL)
2106 new_draw_info (NDI_UNIQUE, 0, op, 2044 {
2107 "The scroll just doesn't make sense!"); 2045 new_draw_info (NDI_UNIQUE, 0, op, "The scroll just doesn't make sense!");
2108 return; 2046 return;
2109 } 2047 }
2110 2048
2111 if(op->type==PLAYER) { 2049 if (op->type == PLAYER)
2050 {
2112 /* players need a literacy skill to read stuff! */ 2051 /* players need a literacy skill to read stuff! */
2113 int exp_gain=0; 2052 int exp_gain = 0;
2114 2053
2115 /* hard code literacy - tmp->skill points to where the exp 2054 /* hard code literacy - tmp->skill points to where the exp
2116 * should go for anything killed by the spell. 2055 * should go for anything killed by the spell.
2117 */ 2056 */
2118 skop = find_skill_by_name(op, skill_names[SK_LITERACY]); 2057 skop = find_skill_by_name (op, skill_names[SK_LITERACY]);
2119 2058
2120 if ( ! skop) { 2059 if (!skop)
2121 new_draw_info(NDI_UNIQUE, 0,op, 2060 {
2122 "You are unable to decipher the strange symbols."); 2061 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to decipher the strange symbols.");
2123 return; 2062 return;
2124 } 2063 }
2125 2064
2126 if((exp_gain = calc_skill_exp(op,tmp, skop))) 2065 if ((exp_gain = calc_skill_exp (op, tmp, skop)))
2127 change_exp(op,exp_gain, skop->skill, 0); 2066 change_exp (op, exp_gain, skop->skill, 0);
2128 } 2067 }
2129 2068
2130 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED)) 2069 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
2131 identify(tmp); 2070 identify (tmp);
2132 2071
2133 new_draw_info_format(NDI_BLACK, 0, op, 2072 new_draw_info_format (NDI_BLACK, 0, op, "The scroll of %s turns to dust.", &tmp->inv->name);
2134 "The scroll of %s turns to dust.", tmp->inv->name);
2135 2073
2136 2074
2137 cast_spell(op,tmp,dir,tmp->inv, NULL); 2075 cast_spell (op, tmp, dir, tmp->inv, NULL);
2138 decrease_ob(tmp); 2076 decrease_ob (tmp);
2139} 2077}
2140 2078
2141/** 2079/**
2142 * Applies a treasure object - by default, chest. op 2080 * Applies a treasure object - by default, chest. op
2143 * is the person doing the applying, tmp is the treasure 2081 * is the person doing the applying, tmp is the treasure
2144 * chest. 2082 * chest.
2145 */ 2083 */
2084static void
2146static void apply_treasure (object *op, object *tmp) 2085apply_treasure (object *op, object *tmp)
2147{ 2086{
2148 object *treas; 2087 object *treas;
2149 tag_t tmp_tag = tmp->count, op_tag = op->count;
2150 2088
2151 2089
2152 /* Nice side effect of new treasure creation method is that the treasure 2090 /* Nice side effect of new treasure creation method is that the treasure
2153 * for the chest is done when the chest is created, and put into the chest 2091 * for the chest is done when the chest is created, and put into the chest
2154 * inventory. So that when the chest burns up, the items still exist. Also 2092 * inventory. So that when the chest burns up, the items still exist. Also
2155 * prevents people fromt moving chests to more difficult maps to get better 2093 * prevents people fromt moving chests to more difficult maps to get better
2156 * treasure 2094 * treasure
2157 */ 2095 */
2158 2096
2159 treas = tmp->inv; 2097 treas = tmp->inv;
2160 if(treas==NULL) { 2098 if (treas == NULL)
2099 {
2161 new_draw_info(NDI_UNIQUE, 0,op,"The chest was empty."); 2100 new_draw_info (NDI_UNIQUE, 0, op, "The chest was empty.");
2162 decrease_ob(tmp);
2163 return;
2164 }
2165 while (tmp->inv) {
2166 treas = tmp->inv;
2167
2168 remove_ob(treas);
2169 new_draw_info_format(NDI_UNIQUE, 0, op, "You find %s in the chest.",
2170 query_name(treas));
2171
2172 treas->x=op->x;
2173 treas->y=op->y;
2174 treas = insert_ob_in_map (treas, op->map, op,INS_BELOW_ORIGINATOR);
2175
2176 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level
2177 && QUERY_FLAG (op, FLAG_ALIVE))
2178 spring_trap (treas, op);
2179 /* If either player or container was destroyed, no need to do
2180 * further processing. I think this should be enclused with
2181 * spring trap above, as I don't think there is otherwise
2182 * any way for the treasure chest or player to get killed
2183 */
2184 if (was_destroyed (op, op_tag) || was_destroyed (tmp, tmp_tag))
2185 break;
2186 }
2187
2188 if ( ! was_destroyed (tmp, tmp_tag) && tmp->inv == NULL)
2189 decrease_ob (tmp); 2101 decrease_ob (tmp);
2102 return;
2103 }
2104 while (tmp->inv)
2105 {
2106 treas = tmp->inv;
2107
2108 remove_ob (treas);
2109 new_draw_info_format (NDI_UNIQUE, 0, op, "You find %s in the chest.", query_name (treas));
2110
2111 treas->x = op->x;
2112 treas->y = op->y;
2113 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR);
2114
2115 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && QUERY_FLAG (op, FLAG_ALIVE))
2116 spring_trap (treas, op);
2117 /* If either player or container was destroyed, no need to do
2118 * further processing. I think this should be enclused with
2119 * spring trap above, as I don't think there is otherwise
2120 * any way for the treasure chest or player to get killed
2121 */
2122 if (op->destroyed () || tmp->destroyed ())
2123 break;
2124 }
2125
2126 if (!tmp->destroyed () && tmp->inv == NULL)
2127 decrease_ob (tmp);
2190 2128
2191} 2129}
2192 2130
2193/** 2131/**
2194 * op eats food. 2132 * op eats food.
2195 * If player, takes care of messages and dragon special food. 2133 * If player, takes care of messages and dragon special food.
2196 */ 2134 */
2135static void
2197static void apply_food (object *op, object *tmp) 2136apply_food (object *op, object *tmp)
2198{ 2137{
2199 int capacity_remaining; 2138 int capacity_remaining;
2200 2139
2201 if(op->type!=PLAYER) 2140 if (op->type != PLAYER)
2202 op->stats.hp=op->stats.maxhp; 2141 op->stats.hp = op->stats.maxhp;
2203 else { 2142 else
2143 {
2204 /* check if this is a dragon (player), eating some flesh */ 2144 /* check if this is a dragon (player), eating some flesh */
2205 if (tmp->type==FLESH && is_dragon_pl(op) && dragon_eat_flesh(op, tmp)) 2145 if (tmp->type == FLESH && is_dragon_pl (op) && dragon_eat_flesh (op, tmp))
2206 ; 2146 ;
2207 else { 2147 else
2148 {
2208 /* usual case - no dragon meal: */ 2149 /* usual case - no dragon meal: */
2209 if(op->stats.food+tmp->stats.food>999) { 2150 if (op->stats.food + tmp->stats.food > 999)
2151 {
2210 if(tmp->type==FOOD || tmp->type==FLESH) 2152 if (tmp->type == FOOD || tmp->type == FLESH)
2211 new_draw_info(NDI_UNIQUE, 0,op,"You feel full, but what a waste of food!"); 2153 new_draw_info (NDI_UNIQUE, 0, op, "You feel full, but what a waste of food!");
2212 else 2154 else
2213 new_draw_info(NDI_UNIQUE, 0,op,"Most of the drink goes down your face not your throat!"); 2155 new_draw_info (NDI_UNIQUE, 0, op, "Most of the drink goes down your face not your throat!");
2214 } 2156 }
2215 2157
2216 if(!QUERY_FLAG(tmp, FLAG_CURSED)) { 2158 if (!QUERY_FLAG (tmp, FLAG_CURSED))
2159 {
2217 char buf[MAX_BUF]; 2160 char buf[MAX_BUF];
2218 2161
2219 if (!is_dragon_pl(op)) { 2162 if (!is_dragon_pl (op))
2163 {
2220 /* eating message for normal players*/ 2164 /* eating message for normal players */
2221 if(tmp->type==DRINK) 2165 if (tmp->type == DRINK)
2222 sprintf(buf,"Ahhh...that %s tasted good.",tmp->name); 2166 sprintf (buf, "Ahhh...that %s tasted good.", &tmp->name);
2223 else 2167 else
2224 sprintf(buf,"The %s tasted %s",tmp->name, 2168 sprintf (buf, "The %s tasted %s", &tmp->name, tmp->type == FLESH ? "terrible!" : "good.");
2225 tmp->type==FLESH?"terrible!":"good."); 2169 }
2226 } 2170 else
2227 else { 2171 {
2228 /* eating message for dragon players*/ 2172 /* eating message for dragon players */
2229 sprintf(buf,"The %s tasted terrible!",tmp->name); 2173 sprintf (buf, "The %s tasted terrible!", &tmp->name);
2230 } 2174 }
2231 2175
2232 new_draw_info(NDI_UNIQUE, 0,op,buf); 2176 new_draw_info (NDI_UNIQUE, 0, op, buf);
2233 capacity_remaining = 999 - op->stats.food; 2177 capacity_remaining = 999 - op->stats.food;
2234 op->stats.food+=tmp->stats.food; 2178 op->stats.food += tmp->stats.food;
2235 if(capacity_remaining < tmp->stats.food) 2179 if (capacity_remaining < tmp->stats.food)
2236 op->stats.hp += capacity_remaining / 50; 2180 op->stats.hp += capacity_remaining / 50;
2237 else 2181 else
2238 op->stats.hp+=tmp->stats.food/50; 2182 op->stats.hp += tmp->stats.food / 50;
2239 if(op->stats.hp>op->stats.maxhp) 2183 if (op->stats.hp > op->stats.maxhp)
2240 op->stats.hp=op->stats.maxhp; 2184 op->stats.hp = op->stats.maxhp;
2241 if (op->stats.food > 999) 2185 if (op->stats.food > 999)
2242 op->stats.food = 999; 2186 op->stats.food = 999;
2243 } 2187 }
2244 2188
2245 /* special food hack -b.t. */ 2189 /* special food hack -b.t. */
2246 if(tmp->title || QUERY_FLAG(tmp,FLAG_CURSED)) 2190 if (tmp->title || QUERY_FLAG (tmp, FLAG_CURSED))
2247 eat_special_food(op,tmp); 2191 eat_special_food (op, tmp);
2248 } 2192 }
2249 } 2193 }
2250 handle_apply_yield(tmp); 2194 handle_apply_yield (tmp);
2251 decrease_ob(tmp); 2195 decrease_ob (tmp);
2252} 2196}
2253 2197
2254/** 2198/**
2255 * A dragon is eating some flesh. If the flesh contains resistances, 2199 * A dragon is eating some flesh. If the flesh contains resistances,
2256 * there is a chance for the dragon's skin to get improved. 2200 * there is a chance for the dragon's skin to get improved.
2259 * object *op the object (dragon player) eating the flesh 2203 * object *op the object (dragon player) eating the flesh
2260 * object *meal the flesh item, getting chewed in dragon's mouth 2204 * object *meal the flesh item, getting chewed in dragon's mouth
2261 * return: 2205 * return:
2262 * int 1 if eating successful, 0 if it doesn't work 2206 * int 1 if eating successful, 0 if it doesn't work
2263 */ 2207 */
2208int
2264int dragon_eat_flesh(object *op, object *meal) { 2209dragon_eat_flesh (object *op, object *meal)
2210{
2265 object *skin = NULL; /* pointer to dragon skin force*/ 2211 object *skin = NULL; /* pointer to dragon skin force */
2266 object *abil = NULL; /* pointer to dragon ability force*/ 2212 object *abil = NULL; /* pointer to dragon ability force */
2267 object *tmp = NULL; /* tmp. object */ 2213 object *tmp = NULL; /* tmp. object */
2268 2214
2269 char buf[MAX_BUF]; /* tmp. string buffer */ 2215 char buf[MAX_BUF]; /* tmp. string buffer */
2270 double chance; /* improvement-chance of one resistance type */ 2216 double chance; /* improvement-chance of one resistance type */
2271 double totalchance=1; /* total chance of gaining one resistance */ 2217 double totalchance = 1; /* total chance of gaining one resistance */
2272 double bonus=0; /* level bonus (improvement is easier at lowlevel) */ 2218 double bonus = 0; /* level bonus (improvement is easier at lowlevel) */
2273 double mbonus=0; /* monster bonus */ 2219 double mbonus = 0; /* monster bonus */
2274 int atnr_winner[NROFATTACKS]; /* winning candidates for resistance improvement */ 2220 int atnr_winner[NROFATTACKS]; /* winning candidates for resistance improvement */
2275 int winners=0; /* number of winners */ 2221 int winners = 0; /* number of winners */
2276 int i; /* index */ 2222 int i; /* index */
2277 2223
2278 /* let's make sure and doublecheck the parameters */ 2224 /* let's make sure and doublecheck the parameters */
2279 if (meal->type!=FLESH || !is_dragon_pl(op)) 2225 if (meal->type != FLESH || !is_dragon_pl (op))
2280 return 0; 2226 return 0;
2281 2227
2282 /* now grab the 'dragon_skin'- and 'dragon_ability'-forces 2228 /* now grab the 'dragon_skin'- and 'dragon_ability'-forces
2283 from the player's inventory */ 2229 from the player's inventory */
2284 for (tmp=op->inv; tmp!=NULL; tmp=tmp->below) { 2230 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
2231 {
2285 if (tmp->type == FORCE) { 2232 if (tmp->type == FORCE)
2233 {
2286 if (strcmp(tmp->arch->name, "dragon_skin_force")==0) 2234 if (strcmp (tmp->arch->name, "dragon_skin_force") == 0)
2287 skin = tmp; 2235 skin = tmp;
2288 else if (strcmp(tmp->arch->name, "dragon_ability_force")==0) 2236 else if (strcmp (tmp->arch->name, "dragon_ability_force") == 0)
2289 abil = tmp; 2237 abil = tmp;
2290 } 2238 }
2291 } 2239 }
2292 2240
2293 /* if either skin or ability are missing, this is an old player 2241 /* if either skin or ability are missing, this is an old player
2294 which is not to be considered a dragon -> bail out */ 2242 which is not to be considered a dragon -> bail out */
2295 if (skin == NULL || abil == NULL) return 0; 2243 if (skin == NULL || abil == NULL)
2296 2244 return 0;
2245
2297 /* now start by filling stomache and health, according to food-value */ 2246 /* now start by filling stomache and health, according to food-value */
2298 if((999 - op->stats.food) < meal->stats.food) 2247 if ((999 - op->stats.food) < meal->stats.food)
2299 op->stats.hp += (999 - op->stats.food) / 50; 2248 op->stats.hp += (999 - op->stats.food) / 50;
2300 else 2249 else
2301 op->stats.hp += meal->stats.food/50; 2250 op->stats.hp += meal->stats.food / 50;
2302 if(op->stats.hp>op->stats.maxhp) 2251 if (op->stats.hp > op->stats.maxhp)
2303 op->stats.hp=op->stats.maxhp; 2252 op->stats.hp = op->stats.maxhp;
2304 2253
2305 op->stats.food = MIN(999, op->stats.food + meal->stats.food); 2254 op->stats.food = MIN (999, op->stats.food + meal->stats.food);
2306 2255
2307 /*LOG(llevDebug, "-> player: %d, flesh: %d\n", op->level, meal->level);*/ 2256 /*LOG(llevDebug, "-> player: %d, flesh: %d\n", op->level, meal->level); */
2308 2257
2309 /* on to the interesting part: chances for adding resistance */ 2258 /* on to the interesting part: chances for adding resistance */
2310 for (i=0; i<NROFATTACKS; i++) { 2259 for (i = 0; i < NROFATTACKS; i++)
2260 {
2311 if (meal->resist[i] > 0 && atnr_is_dragon_enabled(i)) { 2261 if (meal->resist[i] > 0 && atnr_is_dragon_enabled (i))
2262 {
2312 /* got positive resistance, now calculate improvement chance (0-100) */ 2263 /* got positive resistance, now calculate improvement chance (0-100) */
2313 2264
2314 /* this bonus makes resistance increase easier at lower levels */ 2265 /* this bonus makes resistance increase easier at lower levels */
2315 bonus = (settings.max_level - op->level) * 30. / ((double)settings.max_level); 2266 bonus = (settings.max_level - op->level) * 30. / ((double) settings.max_level);
2316 if (i == abil->stats.exp) 2267 if (i == abil->stats.exp)
2317 bonus += 5; /* additional bonus for resistance of ability-focus */ 2268 bonus += 5; /* additional bonus for resistance of ability-focus */
2318 2269
2319 /* monster bonus increases with level, because high-level 2270 /* monster bonus increases with level, because high-level
2320 flesh is too rare */ 2271 flesh is too rare */
2321 mbonus = op->level * 20. / ((double)settings.max_level); 2272 mbonus = op->level * 20. / ((double) settings.max_level);
2322 2273
2323 chance = (((double)MIN(op->level+bonus, meal->level+bonus+mbonus))*100. / 2274 chance = (((double) MIN (op->level + bonus, meal->level + bonus + mbonus)) * 100. /
2324 ((double)settings.max_level)) - skin->resist[i]; 2275 ((double) settings.max_level)) - skin->resist[i];
2325 2276
2326 if (chance >= 0.) 2277 if (chance >= 0.)
2327 chance += 1.; 2278 chance += 1.;
2328 else 2279 else
2329 chance = (chance < -12) ? 0. : 1./pow(2., -chance); 2280 chance = (chance < -12) ? 0. : 1. / pow (2., -chance);
2330 2281
2331 /* chance is proportional to amount of resistance (max. 50) */ 2282 /* chance is proportional to amount of resistance (max. 50) */
2332 chance *= ((double)(MIN(meal->resist[i], 50)))/50.; 2283 chance *= ((double) (MIN (meal->resist[i], 50))) / 50.;
2333 2284
2334 /* doubled chance for resistance of ability-focus */ 2285 /* doubled chance for resistance of ability-focus */
2335 if (i == abil->stats.exp) 2286 if (i == abil->stats.exp)
2336 chance = MIN(100., chance*2.); 2287 chance = MIN (100., chance * 2.);
2337 2288
2338 /* now make the throw and save all winners (Don't insert luck bonus here!) */ 2289 /* now make the throw and save all winners (Don't insert luck bonus here!) */
2339 if (RANDOM()%10000 < (int)(chance*100)) { 2290 if (RANDOM () % 10000 < (int) (chance * 100))
2291 {
2340 atnr_winner[winners] = i; 2292 atnr_winner[winners] = i;
2341 winners++; 2293 winners++;
2342 } 2294 }
2343 2295
2344 if (chance >= 0.01 ) totalchance *= 1 - chance/100; 2296 if (chance >= 0.01)
2345 2297 totalchance *= 1 - chance / 100;
2298
2346 /*LOG(llevDebug, " %s: bonus %.1f, chance %.1f\n", attacks[i], bonus, chance);*/ 2299 /*LOG(llevDebug, " %s: bonus %.1f, chance %.1f\n", attacks[i], bonus, chance); */
2347 } 2300 }
2348 } 2301 }
2349 2302
2350 /* inverse totalchance as until now we have the failure-chance */ 2303 /* inverse totalchance as until now we have the failure-chance */
2351 totalchance = 100 - totalchance*100; 2304 totalchance = 100 - totalchance * 100;
2352 /* print message according to totalchance */ 2305 /* print message according to totalchance */
2353 if (totalchance > 50.) 2306 if (totalchance > 50.)
2354 sprintf(buf, "Hmm! The %s tasted delicious!", meal->name); 2307 sprintf (buf, "Hmm! The %s tasted delicious!", &meal->name);
2355 else if (totalchance > 10.) 2308 else if (totalchance > 10.)
2356 sprintf(buf, "The %s tasted very good.", meal->name); 2309 sprintf (buf, "The %s tasted very good.", &meal->name);
2357 else if (totalchance > 1.) 2310 else if (totalchance > 1.)
2358 sprintf(buf, "The %s tasted good.", meal->name); 2311 sprintf (buf, "The %s tasted good.", &meal->name);
2359 else if (totalchance > 0.1) 2312 else if (totalchance > 0.1)
2360 sprintf(buf, "The %s tasted bland.", meal->name); 2313 sprintf (buf, "The %s tasted bland.", &meal->name);
2361 else if (totalchance >= 0.01) 2314 else if (totalchance >= 0.01)
2362 sprintf(buf, "The %s had a boring taste.", meal->name); 2315 sprintf (buf, "The %s had a boring taste.", &meal->name);
2363 else if (meal->last_eat > 0 && atnr_is_dragon_enabled(meal->last_eat)) 2316 else if (meal->last_eat > 0 && atnr_is_dragon_enabled (meal->last_eat))
2364 sprintf(buf, "The %s tasted strange.", meal->name); 2317 sprintf (buf, "The %s tasted strange.", &meal->name);
2365 else 2318 else
2366 sprintf(buf, "The %s had no taste.", meal->name); 2319 sprintf (buf, "The %s had no taste.", &meal->name);
2367 new_draw_info(NDI_UNIQUE, 0, op, buf); 2320 new_draw_info (NDI_UNIQUE, 0, op, buf);
2368 2321
2369 /* now choose a winner if we have any */ 2322 /* now choose a winner if we have any */
2370 i = -1; 2323 i = -1;
2371 if (winners>0) 2324 if (winners > 0)
2372 i = atnr_winner[RANDOM()%winners]; 2325 i = atnr_winner[RANDOM () % winners];
2373 2326
2374 if (i >= 0 && i < NROFATTACKS && skin->resist[i] < 95) { 2327 if (i >= 0 && i < NROFATTACKS && skin->resist[i] < 95)
2328 {
2375 /* resistance increased! */ 2329 /* resistance increased! */
2376 skin->resist[i]++; 2330 skin->resist[i]++;
2377 fix_player(op); 2331 fix_player (op);
2378 2332
2379 sprintf(buf, "Your skin is now more resistant to %s!", change_resist_msg[i]); 2333 sprintf (buf, "Your skin is now more resistant to %s!", change_resist_msg[i]);
2380 new_draw_info(NDI_UNIQUE|NDI_RED, 0, op, buf); 2334 new_draw_info (NDI_UNIQUE | NDI_RED, 0, op, buf);
2381 } 2335 }
2382 2336
2383 /* if this flesh contains a new ability focus, we mark it 2337 /* if this flesh contains a new ability focus, we mark it
2384 into the ability_force and it will take effect on next level */ 2338 into the ability_force and it will take effect on next level */
2385 if (meal->last_eat > 0 && atnr_is_dragon_enabled(meal->last_eat) 2339 if (meal->last_eat > 0 && atnr_is_dragon_enabled (meal->last_eat) && meal->last_eat != abil->last_eat)
2386 && meal->last_eat != abil->last_eat) { 2340 {
2387 abil->last_eat = meal->last_eat; /* write: last_eat <new attnr focus> */ 2341 abil->last_eat = meal->last_eat; /* write: last_eat <new attnr focus> */
2388 2342
2389 if (meal->last_eat != abil->stats.exp) { 2343 if (meal->last_eat != abil->stats.exp)
2344 {
2390 sprintf(buf, "Your metabolism prepares to focus on %s!", 2345 sprintf (buf, "Your metabolism prepares to focus on %s!", change_resist_msg[meal->last_eat]);
2391 change_resist_msg[meal->last_eat]);
2392 new_draw_info(NDI_UNIQUE, 0, op, buf); 2346 new_draw_info (NDI_UNIQUE, 0, op, buf);
2393 sprintf(buf, "The change will happen at level %d", abil->level + 1); 2347 sprintf (buf, "The change will happen at level %d", abil->level + 1);
2394 new_draw_info(NDI_UNIQUE, 0, op, buf); 2348 new_draw_info (NDI_UNIQUE, 0, op, buf);
2395 } 2349 }
2396 else { 2350 else
2351 {
2397 sprintf(buf, "Your metabolism will continue to focus on %s.", 2352 sprintf (buf, "Your metabolism will continue to focus on %s.", change_resist_msg[meal->last_eat]);
2398 change_resist_msg[meal->last_eat]);
2399 new_draw_info(NDI_UNIQUE, 0, op, buf); 2353 new_draw_info (NDI_UNIQUE, 0, op, buf);
2400 abil->last_eat = 0; 2354 abil->last_eat = 0;
2401 } 2355 }
2402 } 2356 }
2403 return 1; 2357 return 1;
2404} 2358}
2405 2359
2360static void
2406static void apply_savebed (object *pl) 2361apply_savebed (object *pl)
2407{ 2362{
2408#ifndef COZY_SERVER 2363#ifndef COZY_SERVER
2409 if(!pl->contr->name_changed||!pl->stats.exp) { 2364 if (!pl->contr->name_changed || !pl->stats.exp)
2365 {
2410 new_draw_info(NDI_UNIQUE, 0,pl,"You don't deserve to save your character yet."); 2366 new_draw_info (NDI_UNIQUE, 0, pl, "You don't deserve to save your character yet.");
2411 return; 2367 return;
2412 } 2368 }
2413#endif 2369#endif
2370 INVOKE_PLAYER (LOGOUT, pl->contr);
2414 /* Need to call terminate_all_pets() before we remove the player ob */ 2371 /* Need to call terminate_all_pets() before we remove the player ob */
2415 terminate_all_pets(pl); 2372 terminate_all_pets (pl);
2416 remove_ob(pl); 2373 remove_ob (pl);
2417 pl->direction=0; 2374 pl->direction = 0;
2418 new_draw_info_format(NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, pl, 2375 new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, pl, "%s leaves the game.", &pl->name);
2419 "%s leaves the game.",pl->name); 2376
2420
2421 /* update respawn position */ 2377 /* update respawn position */
2422 strcpy(pl->contr->savebed_map, pl->map->path); 2378 strcpy (pl->contr->savebed_map, pl->map->path);
2423 pl->contr->bed_x = pl->x; 2379 pl->contr->bed_x = pl->x;
2424 pl->contr->bed_y = pl->y; 2380 pl->contr->bed_y = pl->y;
2425 2381
2426 strcpy(pl->contr->killer,"left"); 2382 strcpy (pl->contr->killer, "left");
2427 check_score(pl); /* Always check score */ 2383 check_score (pl); /* Always check score */
2428 (void)save_player(pl,0); 2384 (void) save_player (pl, 0);
2429 pl->map->players--; 2385 pl->map->players--;
2430#if MAP_MAXTIMEOUT 2386#if MAP_MAXTIMEOUT
2431 MAP_SWAP_TIME(pl->map) = MAP_TIMEOUT(pl->map); 2387 MAP_SWAP_TIME (pl->map) = MAP_TIMEOUT (pl->map);
2432#endif 2388#endif
2433 play_again(pl); 2389 play_again (pl);
2434 pl->speed = 0; 2390 pl->speed = 0;
2435 update_ob_speed(pl); 2391 update_ob_speed (pl);
2436} 2392}
2437 2393
2438/** 2394/**
2439 * Handles applying an improve armor scroll. 2395 * Handles applying an improve armor scroll.
2440 * Does some sanity checks, then calls improve_armour. 2396 * Does some sanity checks, then calls improve_armour.
2441 */ 2397 */
2398static void
2442static void apply_armour_improver (object *op, object *tmp) 2399apply_armour_improver (object *op, object *tmp)
2443{ 2400{
2444 object *armor; 2401 object *armor;
2445 2402
2446 if (!QUERY_FLAG(op, FLAG_WIZCAST) && (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC)) { 2403 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC))
2404 {
2447 new_draw_info(NDI_UNIQUE, 0,op,"Something blocks the magic of the scroll."); 2405 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the scroll.");
2448 return;
2449 }
2450 armor=find_marked_object(op);
2451 if ( ! armor) {
2452 new_draw_info(NDI_UNIQUE, 0, op, "You need to mark an armor object.");
2453 return; 2406 return;
2454 } 2407 }
2408 armor = find_marked_object (op);
2409 if (!armor)
2410 {
2411 new_draw_info (NDI_UNIQUE, 0, op, "You need to mark an armor object.");
2412 return;
2413 }
2455 if (armor->type != ARMOUR 2414 if (armor->type != ARMOUR
2456 && armor->type != CLOAK 2415 && armor->type != CLOAK
2457 && armor->type != BOOTS && armor->type != GLOVES 2416 && armor->type != BOOTS && armor->type != GLOVES && armor->type != BRACERS && armor->type != SHIELD && armor->type != HELMET)
2458 && armor->type != BRACERS && armor->type != SHIELD
2459 && armor->type != HELMET)
2460 { 2417 {
2461 new_draw_info(NDI_UNIQUE, 0,op,"Your marked item is not armour!\n"); 2418 new_draw_info (NDI_UNIQUE, 0, op, "Your marked item is not armour!\n");
2462 return; 2419 return;
2463 } 2420 }
2464 2421
2465 new_draw_info(NDI_UNIQUE, 0,op,"Applying armour enchantment."); 2422 new_draw_info (NDI_UNIQUE, 0, op, "Applying armour enchantment.");
2466 improve_armour(op,tmp,armor); 2423 improve_armour (op, tmp, armor);
2467} 2424}
2468 2425
2469 2426
2427extern void
2470extern void apply_poison (object *op, object *tmp) 2428apply_poison (object *op, object *tmp)
2471{ 2429{
2472 if (op->type == PLAYER) { 2430 if (op->type == PLAYER)
2431 {
2473 play_sound_player_only(op->contr, SOUND_DRINK_POISON,0,0); 2432 play_sound_player_only (op->contr, SOUND_DRINK_POISON, 0, 0);
2474 new_draw_info(NDI_UNIQUE, 0,op,"Yech! That tasted poisonous!"); 2433 new_draw_info (NDI_UNIQUE, 0, op, "Yech! That tasted poisonous!");
2475 strcpy(op->contr->killer,"poisonous booze"); 2434 strcpy (op->contr->killer, "poisonous booze");
2476 } 2435 }
2477 if (tmp->stats.hp > 0) { 2436 if (tmp->stats.hp > 0)
2437 {
2478 LOG(llevDebug,"Trying to poison player/monster for %d hp\n", 2438 LOG (llevDebug, "Trying to poison player/monster for %d hp\n", tmp->stats.hp);
2479 tmp->stats.hp);
2480 hit_player(op, tmp->stats.hp, tmp, AT_POISON, 1); 2439 hit_player (op, tmp->stats.hp, tmp, AT_POISON, 1);
2481 } 2440 }
2482 op->stats.food-=op->stats.food/4; 2441 op->stats.food -= op->stats.food / 4;
2483 handle_apply_yield(tmp); 2442 handle_apply_yield (tmp);
2484 decrease_ob(tmp); 2443 decrease_ob (tmp);
2485} 2444}
2486 2445
2487/** 2446/**
2488 * This fonction return true if the exit is not a 2 ways one or it is 2 ways, valid exit. 2447 * This fonction return true if the exit is not a 2 ways one or it is 2 ways, valid exit.
2489 * A valid 2 way exit means: 2448 * A valid 2 way exit means:
2494 * 2453 *
2495 * Note: a owner in a 2 way exit is saved as the owner's name 2454 * Note: a owner in a 2 way exit is saved as the owner's name
2496 * in the field exit->name cause the field exit->owner doesn't 2455 * in the field exit->name cause the field exit->owner doesn't
2497 * survive in the swapping (in fact the whole exit doesn't survive). 2456 * survive in the swapping (in fact the whole exit doesn't survive).
2498 */ 2457 */
2458int
2499int is_legal_2ways_exit (object* op, object *exit) 2459is_legal_2ways_exit (object *op, object *exit)
2500 { 2460{
2501 object * tmp; 2461 object *tmp;
2502 object * exit_owner; 2462 object *exit_owner;
2503 player * pp; 2463 player *pp;
2504 mapstruct * exitmap; 2464 maptile *exitmap;
2505 if (exit->stats.exp!=1) return 1; /*This is not a 2 way, so it is legal*/ 2465
2506 if (!has_been_loaded(EXIT_PATH(exit)) && exit->race) return 0; /* This is a reset town portal */ 2466 if (exit->stats.exp != 1)
2467 return 1; /*This is not a 2 way, so it is legal */
2468 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race)
2469 return 0; /* This is a reset town portal */
2507 /* To know if an exit has a correspondant, we look at 2470 /* To know if an exit has a correspondant, we look at
2508 * all the exits in destination and try to find one with same path as 2471 * all the exits in destination and try to find one with same path as
2509 * the current exit's position */ 2472 * the current exit's position */
2510 if (!strncmp(EXIT_PATH (exit), settings.localdir, strlen(settings.localdir))) 2473 if (!strncmp (EXIT_PATH (exit), settings.localdir, strlen (settings.localdir)))
2511 exitmap = ready_map_name(EXIT_PATH (exit), MAP_PLAYER_UNIQUE); 2474 exitmap = ready_map_name (EXIT_PATH (exit), MAP_PLAYER_UNIQUE);
2475 else
2512 else exitmap = ready_map_name(EXIT_PATH (exit), 0); 2476 exitmap = ready_map_name (EXIT_PATH (exit), 0);
2513 if (exitmap) 2477 if (exitmap)
2514 { 2478 {
2515 tmp=get_map_ob (exitmap,EXIT_X(exit),EXIT_Y(exit)); 2479 tmp = get_map_ob (exitmap, EXIT_X (exit), EXIT_Y (exit));
2516 if (!tmp) return 0; 2480 if (!tmp)
2481 return 0;
2517 for ( (tmp=get_map_ob(exitmap,EXIT_X(exit),EXIT_Y(exit)));tmp;tmp=tmp->above) 2482 for ((tmp = get_map_ob (exitmap, EXIT_X (exit), EXIT_Y (exit))); tmp; tmp = tmp->above)
2518 { 2483 {
2519 if (tmp->type!=EXIT) continue; /*Not an exit*/ 2484 if (tmp->type != EXIT)
2520 if (!EXIT_PATH (tmp)) continue; /*Not a valid exit*/ 2485 continue; /*Not an exit */
2521 if ( (EXIT_X(tmp)!=exit->x) || (EXIT_Y(tmp)!=exit->y)) continue; /*Not in the same place*/ 2486 if (!EXIT_PATH (tmp))
2522 if (strcmp(exit->map->path,EXIT_PATH(tmp))!=0) continue; /*Not in the same map*/ 2487 continue; /*Not a valid exit */
2488 if ((EXIT_X (tmp) != exit->x) || (EXIT_Y (tmp) != exit->y))
2489 continue; /*Not in the same place */
2490 if (strcmp (exit->map->path, EXIT_PATH (tmp)) != 0)
2491 continue; /*Not in the same map */
2523 2492
2524 /* From here we have found the exit is valid. However we do 2493 /* From here we have found the exit is valid. However we do
2525 * here the check of the exit owner. It is important for the 2494 * here the check of the exit owner. It is important for the
2526 * town portals to prevent strangers from visiting your appartments 2495 * town portals to prevent strangers from visiting your appartments
2527 */ 2496 */
2497 if (!exit->race)
2528 if (!exit->race) return 1; /*No owner, free for all!*/ 2498 return 1; /*No owner, free for all! */
2529 exit_owner=NULL; 2499 exit_owner = NULL;
2530 for (pp=first_player;pp;pp=pp->next) 2500 for (pp = first_player; pp; pp = pp->next)
2531 { 2501 {
2532 if (!pp->ob) continue; 2502 if (!pp->ob)
2503 continue;
2533 if (pp->ob->name!=exit->race) continue; 2504 if (pp->ob->name != exit->race)
2505 continue;
2534 exit_owner= pp->ob; /*We found a player which correspond to the player name*/ 2506 exit_owner = pp->ob; /*We found a player which correspond to the player name */
2535 break; 2507 break;
2536 } 2508 }
2537 if (!exit_owner) return 0; /* No more owner*/ 2509 if (!exit_owner)
2538 if (exit_owner->contr==op->contr) return 1; /*It is your exit*/ 2510 return 0; /* No more owner */
2511 if (exit_owner->contr == op->contr)
2512 return 1; /*It is your exit */
2539 if ( exit_owner && /*There is a owner*/ 2513 if (exit_owner && /*There is a owner */
2540 (op->contr) && /*A player tries to pass */ 2514 (op->contr) && /*A player tries to pass */
2541 ( (exit_owner->contr->party==NULL) || /*No pass if controller has no party*/ 2515 ((exit_owner->contr->party == NULL) || /*No pass if controller has no party */
2542 (exit_owner->contr->party!=op->contr->party)) ) /* Or not the same as op*/ 2516 (exit_owner->contr->party != op->contr->party))) /* Or not the same as op */
2543 return 0; 2517 return 0;
2544 return 1; 2518 return 1;
2545 } 2519 }
2546 } 2520 }
2547 return 0; 2521 return 0;
2548 } 2522}
2549 2523
2550 2524
2551/** 2525/**
2552 * Main apply handler. 2526 * Main apply handler.
2553 * 2527 *
2563 * 2537 *
2564 * aflag is special (always apply/unapply) flags. Nothing is done with 2538 * aflag is special (always apply/unapply) flags. Nothing is done with
2565 * them in this function - they are passed to apply_special 2539 * them in this function - they are passed to apply_special
2566 */ 2540 */
2567 2541
2542int
2568int manual_apply (object *op, object *tmp, int aflag) 2543manual_apply (object *op, object *tmp, int aflag)
2569{ 2544{
2570 if (tmp->head) tmp=tmp->head; 2545 if (tmp->head)
2546 tmp = tmp->head;
2571 2547
2572 if (QUERY_FLAG (tmp, FLAG_UNPAID) && ! QUERY_FLAG (tmp, FLAG_APPLIED)) { 2548 if (QUERY_FLAG (tmp, FLAG_UNPAID) && !QUERY_FLAG (tmp, FLAG_APPLIED))
2549 {
2573 if (op->type == PLAYER) { 2550 if (op->type == PLAYER)
2551 {
2574 new_draw_info (NDI_UNIQUE, 0, op, "You should pay for it first."); 2552 new_draw_info (NDI_UNIQUE, 0, op, "You should pay for it first.");
2575 return 1; 2553 return 1;
2576 } else { 2554 }
2555 else
2556 {
2577 return 0; /* monsters just skip unpaid items */ 2557 return 0; /* monsters just skip unpaid items */
2578 } 2558 }
2559 }
2560
2561 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op)))
2562 return RESULT_INT (0);
2563
2564 switch (tmp->type)
2579 } 2565 {
2580 2566
2581 2567 case CF_HANDLE:
2582 /* Lauwenmark: Handle for plugin apply event */ 2568 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2583 if (execute_event(tmp, EVENT_APPLY,op,NULL,NULL,SCRIPT_FIX_ALL)!=0) 2569 play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE);
2570 tmp->value = tmp->value ? 0 : 1;
2571 SET_ANIMATION (tmp, tmp->value);
2572 update_object (tmp, UP_OBJ_FACE);
2573 push_button (tmp);
2584 return 1; 2574 return 1;
2585 2575
2586 switch (tmp->type) { 2576 case TRIGGER:
2587 2577 if (check_trigger (tmp, op))
2588 case TRANSPORT: 2578 {
2589 return apply_transport(op, tmp, aflag);
2590
2591 case CF_HANDLE:
2592 new_draw_info(NDI_UNIQUE, 0,op,"You turn the handle."); 2579 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2593 play_sound_map(op->map, op->x, op->y, SOUND_TURN_HANDLE);
2594 tmp->value=tmp->value?0:1;
2595 SET_ANIMATION(tmp, tmp->value);
2596 update_object(tmp,UP_OBJ_FACE);
2597 push_button(tmp);
2598 return 1;
2599
2600 case TRIGGER:
2601 if (check_trigger (tmp, op)) {
2602 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2603 play_sound_map (tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE); 2580 play_sound_map (tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE);
2604 } else { 2581 }
2582 else
2583 {
2605 new_draw_info (NDI_UNIQUE, 0, op, "The handle doesn't move."); 2584 new_draw_info (NDI_UNIQUE, 0, op, "The handle doesn't move.");
2606 } 2585 }
2607 return 1; 2586 return 1;
2608 2587
2609 case EXIT: 2588 case EXIT:
2610 if (op->type != PLAYER) 2589 if (op->type != PLAYER)
2611 return 0; 2590 return 0;
2612 if( ! EXIT_PATH (tmp) || !is_legal_2ways_exit(op,tmp)) { 2591 if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp))
2592 {
2613 new_draw_info_format(NDI_UNIQUE, 0, op, "The %s is closed.", 2593 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s is closed.", query_name (tmp));
2614 query_name(tmp)); 2594 }
2615 } else { 2595 else
2596 {
2616 /* Don't display messages for random maps. */ 2597 /* Don't display messages for random maps. */
2617 if (tmp->msg && strncmp(EXIT_PATH(tmp),"/!",2) && 2598 if (tmp->msg && strncmp (EXIT_PATH (tmp), "/!", 2) && strncmp (EXIT_PATH (tmp), "/random/", 8))
2618 strncmp(EXIT_PATH(tmp), "/random/", 8))
2619 new_draw_info (NDI_NAVY, 0, op, tmp->msg); 2599 new_draw_info (NDI_NAVY, 0, op, tmp->msg);
2620 enter_exit(op,tmp); 2600 enter_exit (op, tmp);
2621 } 2601 }
2622 return 1; 2602 return 1;
2623 2603
2624 case SIGN: 2604 case SIGN:
2625 apply_sign (op, tmp, 0); 2605 apply_sign (op, tmp, 0);
2626 return 1; 2606 return 1;
2627 2607
2628 case BOOK: 2608 case BOOK:
2629 if (op->type == PLAYER) { 2609 if (op->type == PLAYER)
2610 {
2630 apply_book (op, tmp); 2611 apply_book (op, tmp);
2631 return 1; 2612 return 1;
2632 } else { 2613 }
2633 return 0; 2614 else
2634 } 2615 {
2616 return 0;
2617 }
2635 2618
2636 case SKILLSCROLL: 2619 case SKILLSCROLL:
2637 if (op->type == PLAYER) { 2620 if (op->type == PLAYER)
2621 {
2638 apply_skillscroll (op, tmp); 2622 apply_skillscroll (op, tmp);
2639 return 1; 2623 return 1;
2640 } 2624 }
2641 return 0; 2625 return 0;
2642 2626
2643 case SPELLBOOK: 2627 case SPELLBOOK:
2644 if (op->type == PLAYER) { 2628 if (op->type == PLAYER)
2629 {
2645 apply_spellbook (op, tmp); 2630 apply_spellbook (op, tmp);
2646 return 1; 2631 return 1;
2647 } 2632 }
2648 return 0; 2633 return 0;
2649 2634
2650 case SCROLL: 2635 case SCROLL:
2651 apply_scroll (op, tmp, 0); 2636 apply_scroll (op, tmp, 0);
2652 return 1; 2637 return 1;
2653 2638
2654 case POTION: 2639 case POTION:
2655 (void) apply_potion(op, tmp); 2640 (void) apply_potion (op, tmp);
2656 return 1; 2641 return 1;
2657 2642
2658 /* Eneq(@csd.uu.se): Handle apply on containers. */ 2643 /* Eneq(@csd.uu.se): Handle apply on containers. */
2659 case CLOSE_CON: 2644 case CLOSE_CON:
2660 if (op->type==PLAYER)
2661 (void) esrv_apply_container (op, tmp->env);
2662 else
2663 (void) apply_container (op, tmp->env);
2664 return 1;
2665
2666 case CONTAINER:
2667 if (op->type==PLAYER)
2668 (void) esrv_apply_container (op, tmp);
2669 else
2670 (void) apply_container (op, tmp);
2671 return 1;
2672
2673 case TREASURE:
2674 if (op->type == PLAYER) { 2645 if (op->type == PLAYER)
2646 (void) esrv_apply_container (op, tmp->env);
2647 else
2648 (void) apply_container (op, tmp->env);
2649 return 1;
2650
2651 case CONTAINER:
2652 if (op->type == PLAYER)
2653 (void) esrv_apply_container (op, tmp);
2654 else
2655 (void) apply_container (op, tmp);
2656 return 1;
2657
2658 case TREASURE:
2659 if (op->type == PLAYER)
2660 {
2675 apply_treasure (op, tmp); 2661 apply_treasure (op, tmp);
2676 return 1; 2662 return 1;
2677 } else { 2663 }
2678 return 0; 2664 else
2679 } 2665 {
2666 return 0;
2667 }
2680 2668
2681 case WEAPON: 2669 case WEAPON:
2682 case ARMOUR: 2670 case ARMOUR:
2683 case BOOTS: 2671 case BOOTS:
2684 case GLOVES: 2672 case GLOVES:
2685 case AMULET: 2673 case AMULET:
2686 case GIRDLE: 2674 case GIRDLE:
2687 case BRACERS: 2675 case BRACERS:
2688 case SHIELD: 2676 case SHIELD:
2689 case HELMET: 2677 case HELMET:
2690 case RING: 2678 case RING:
2691 case CLOAK: 2679 case CLOAK:
2692 case WAND: 2680 case WAND:
2693 case ROD: 2681 case ROD:
2694 case HORN: 2682 case HORN:
2695 case SKILL: 2683 case SKILL:
2696 case BOW: 2684 case BOW:
2697 case LAMP: 2685 case LAMP:
2698 case BUILDER: 2686 case BUILDER:
2699 case SKILL_TOOL: 2687 case SKILL_TOOL:
2700 if (tmp->env != op) 2688 if (tmp->env != op)
2701 return 2; /* not in inventory */ 2689 return 2; /* not in inventory */
2702 (void) apply_special (op, tmp, aflag); 2690 (void) apply_special (op, tmp, aflag);
2703 return 1; 2691 return 1;
2704 2692
2705 case DRINK: 2693 case DRINK:
2706 case FOOD: 2694 case FOOD:
2707 case FLESH: 2695 case FLESH:
2708 apply_food (op, tmp); 2696 apply_food (op, tmp);
2709 return 1; 2697 return 1;
2710 2698
2711 case POISON: 2699 case POISON:
2712 apply_poison (op, tmp); 2700 apply_poison (op, tmp);
2713 return 1; 2701 return 1;
2714 2702
2715 case SAVEBED: 2703 case SAVEBED:
2716 if (op->type == PLAYER) { 2704 if (op->type == PLAYER)
2717 apply_savebed (op); 2705 {
2718 return 1; 2706 apply_savebed (op);
2719 } else { 2707 return 1;
2720 return 0; 2708 }
2721 } 2709 else
2710 {
2711 return 0;
2712 }
2722 2713
2723 case ARMOUR_IMPROVER: 2714 case ARMOUR_IMPROVER:
2724 if (op->type == PLAYER) { 2715 if (op->type == PLAYER)
2716 {
2725 apply_armour_improver (op, tmp); 2717 apply_armour_improver (op, tmp);
2726 return 1; 2718 return 1;
2727 } else { 2719 }
2728 return 0; 2720 else
2729 } 2721 {
2722 return 0;
2723 }
2730 2724
2731 case WEAPON_IMPROVER: 2725 case WEAPON_IMPROVER:
2732 (void) check_improve_weapon(op, tmp); 2726 (void) check_improve_weapon (op, tmp);
2733 return 1; 2727 return 1;
2734 2728
2735 case CLOCK: 2729 case CLOCK:
2736 if (op->type == PLAYER) { 2730 if (op->type == PLAYER)
2737 char buf[MAX_BUF]; 2731 {
2738 timeofday_t tod; 2732 char buf[MAX_BUF];
2733 timeofday_t tod;
2739 2734
2740 get_tod(&tod); 2735 get_tod (&tod);
2741 sprintf(buf, "It is %d minute%s past %d o'clock %s", 2736 sprintf (buf, "It is %d minute%s past %d o'clock %s",
2742 tod.minute+1, ((tod.minute+1 < 2) ? "" : "s"), 2737 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"),
2743 ((tod.hour % 14 == 0) ? 14 : ((tod.hour)%14)), 2738 ((tod.hour % 14 == 0) ? 14 : ((tod.hour) % 14)), ((tod.hour >= 14) ? "pm" : "am"));
2744 ((tod.hour >= 14) ? "pm" : "am"));
2745 play_sound_player_only(op->contr, SOUND_CLOCK,0,0); 2739 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0);
2746 new_draw_info(NDI_UNIQUE, 0,op, buf); 2740 new_draw_info (NDI_UNIQUE, 0, op, buf);
2747 return 1; 2741 return 1;
2748 } else { 2742 }
2749 return 0; 2743 else
2750 } 2744 {
2745 return 0;
2746 }
2751 2747
2752 case MENU: 2748 case MENU:
2753 if (op->type == PLAYER) { 2749 if (op->type == PLAYER)
2754 shop_listing (op); 2750 {
2755 return 1; 2751 shop_listing (op);
2756 } else { 2752 return 1;
2757 return 0; 2753 }
2758 } 2754 else
2755 {
2756 return 0;
2757 }
2759 2758
2760 case POWER_CRYSTAL: 2759 case POWER_CRYSTAL:
2761 apply_power_crystal(op,tmp); /* see egoitem.c */ 2760 apply_power_crystal (op, tmp); /* see egoitem.c */
2762 return 1; 2761 return 1;
2763 2762
2764 case LIGHTER: /* for lighting torches/lanterns/etc */ 2763 case LIGHTER: /* for lighting torches/lanterns/etc */
2765 if (op->type == PLAYER) { 2764 if (op->type == PLAYER)
2766 apply_lighter(op,tmp); 2765 {
2767 return 1; 2766 apply_lighter (op, tmp);
2768 } else { 2767 return 1;
2769 return 0; 2768 }
2770 } 2769 else
2770 {
2771 return 0;
2772 }
2771 2773
2772 case ITEM_TRANSFORMER: 2774 case ITEM_TRANSFORMER:
2773 apply_item_transformer( op, tmp ); 2775 apply_item_transformer (op, tmp);
2774 return 1; 2776 return 1;
2775 2777
2776 default: 2778 default:
2777 return 0; 2779 return 0;
2778 } 2780 }
2779} 2781}
2780 2782
2781 2783
2782/* quiet suppresses the "don't know how to apply" and "you must get it first" 2784/* quiet suppresses the "don't know how to apply" and "you must get it first"
2783 * messages as needed by player_apply_below(). But there can still be 2785 * messages as needed by player_apply_below(). But there can still be
2784 * "but you are floating high above the ground" messages. 2786 * "but you are floating high above the ground" messages.
2785 * 2787 *
2786 * Same return value as apply() function. 2788 * Same return value as apply() function.
2787 */ 2789 */
2790int
2788int player_apply (object *pl, object *op, int aflag, int quiet) 2791player_apply (object *pl, object *op, int aflag, int quiet)
2789{ 2792{
2790 int tmp; 2793 int tmp;
2791 2794
2792 if (op->env == NULL && (pl->move_type & MOVE_FLYING)) { 2795 if (op->env == NULL && (pl->move_type & MOVE_FLYING))
2796 {
2793 /* player is flying and applying object not in inventory */ 2797 /* player is flying and applying object not in inventory */
2794 if ( ! QUERY_FLAG (pl, FLAG_WIZ) && !(op->move_type & MOVE_FLYING)) { 2798 if (!QUERY_FLAG (pl, FLAG_WIZ) && !(op->move_type & MOVE_FLYING))
2799 {
2795 new_draw_info (NDI_UNIQUE, 0, pl, "But you are floating high " 2800 new_draw_info (NDI_UNIQUE, 0, pl, "But you are floating high " "above the ground!");
2796 "above the ground!");
2797 return 0; 2801 return 0;
2798 } 2802 }
2799 } 2803 }
2800 2804
2801 /* Check for PLAYER to avoid a DM to disappear in a puff of smoke if 2805 /* Check for PLAYER to avoid a DM to disappear in a puff of smoke if
2802 * applied. 2806 * applied.
2803 */ 2807 */
2804 if (op->type != PLAYER && QUERY_FLAG (op, FLAG_WAS_WIZ) && ! QUERY_FLAG (pl, FLAG_WAS_WIZ)) 2808 if (op->type != PLAYER && QUERY_FLAG (op, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ))
2805 { 2809 {
2806 play_sound_map (pl->map, pl->x, pl->y, SOUND_OB_EVAPORATE); 2810 play_sound_map (pl->map, pl->x, pl->y, SOUND_OB_EVAPORATE);
2807 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff " 2811 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff " "of smoke!");
2808 "of smoke!");
2809 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion."); 2812 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion.");
2810 remove_ob (op); 2813 remove_ob (op);
2811 free_object (op); 2814 free_object (op);
2812 return 1; 2815 return 1;
2813 } 2816 }
2814 2817
2815 pl->contr->last_used = op; 2818 pl->contr->last_used = op;
2816 pl->contr->last_used_id = op->count; 2819 pl->contr->last_used_id = op->count;
2817 2820
2818 tmp = manual_apply (pl, op, aflag); 2821 tmp = manual_apply (pl, op, aflag);
2819 if ( ! quiet) { 2822 if (!quiet)
2823 {
2820 if (tmp == 0) 2824 if (tmp == 0)
2821 new_draw_info_format (NDI_UNIQUE, 0, pl, 2825 new_draw_info_format (NDI_UNIQUE, 0, pl, "I don't know how to apply the %s.", query_name (op));
2822 "I don't know how to apply the %s.",
2823 query_name (op));
2824 else if (tmp == 2) 2826 else if (tmp == 2)
2825 new_draw_info_format (NDI_UNIQUE, 0, pl, 2827 new_draw_info_format (NDI_UNIQUE, 0, pl, "You must get it first!\n");
2826 "You must get it first!\n");
2827 } 2828 }
2828 return tmp; 2829 return tmp;
2829} 2830}
2830 2831
2831/** 2832/**
2832 * player_apply_below attempts to apply the object 'below' the player. 2833 * player_apply_below attempts to apply the object 'below' the player.
2833 * If the player has an open container, we use that for below, otherwise 2834 * If the player has an open container, we use that for below, otherwise
2834 * we use the ground. 2835 * we use the ground.
2835 */ 2836 */
2836 2837
2838void
2837void player_apply_below (object *pl) 2839player_apply_below (object *pl)
2838{ 2840{
2839 object *tmp, *next; 2841 object *tmp, *next;
2840 int floors; 2842 int floors;
2841 2843
2842 if (pl->contr->transport && pl->contr->transport->type == TRANSPORT) {
2843 apply_transport(pl, pl->contr->transport, 0);
2844 return;
2845 }
2846
2847 /* If using a container, set the starting item to be the top 2844 /* If using a container, set the starting item to be the top
2848 * item in the container. Otherwise, use the map. 2845 * item in the container. Otherwise, use the map.
2849 */ 2846 */
2850 tmp = (pl->container != NULL) ? pl->container->inv : pl->below; 2847 tmp = (pl->container != NULL) ? pl->container->inv : pl->below;
2851 2848
2852 /* This is perhaps more complicated. However, I want to make sure that 2849 /* This is perhaps more complicated. However, I want to make sure that
2853 * we don't use a corrupt pointer for the next object, so we get the 2850 * we don't use a corrupt pointer for the next object, so we get the
2854 * next object in the stack before applying. This is can only be a 2851 * next object in the stack before applying. This is can only be a
2855 * problem if player_apply() has a bug in that it uses the object but does 2852 * problem if player_apply() has a bug in that it uses the object but does
2856 * not return a proper value. 2853 * not return a proper value.
2857 */ 2854 */
2858 for (floors = 0; tmp!=NULL; tmp=next) { 2855 for (floors = 0; tmp != NULL; tmp = next)
2856 {
2859 next = tmp->below; 2857 next = tmp->below;
2860 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 2858 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR))
2861 floors++; 2859 floors++;
2862 else if (floors > 0) 2860 else if (floors > 0)
2863 return; /* process only floor objects after first floor object */ 2861 return; /* process only floor objects after first floor object */
2864 2862
2865 /* If it is visible, player can apply it. If it is applied by 2863 /* If it is visible, player can apply it. If it is applied by
2866 * person moving on it, also activate. Added code to make it 2864 * person moving on it, also activate. Added code to make it
2867 * so that at least one of players movement types be that which 2865 * so that at least one of players movement types be that which
2868 * the item needs. 2866 * the item needs.
2869 */ 2867 */
2870 if ( ! tmp->invisible || (tmp->move_on & pl->move_type)) { 2868 if (!tmp->invisible || (tmp->move_on & pl->move_type))
2869 {
2871 if (player_apply (pl, tmp, 0, 1) == 1) 2870 if (player_apply (pl, tmp, 0, 1) == 1)
2872 return; 2871 return;
2873 } 2872 }
2874 if (floors >= 2) 2873 if (floors >= 2)
2875 return; /* process at most two floor objects */ 2874 return; /* process at most two floor objects */
2876 } 2875 }
2877} 2876}
2878 2877
2879/** 2878/**
2880 * Unapplies specified item. 2879 * Unapplies specified item.
2881 * No check done on cursed/damned. 2880 * No check done on cursed/damned.
2882 * Break this out of apply_special - this is just done 2881 * Break this out of apply_special - this is just done
2883 * to keep the size of apply_special to a more managable size. 2882 * to keep the size of apply_special to a more managable size.
2884 */ 2883 */
2884static int
2885static int unapply_special (object *who, object *op, int aflags) 2885unapply_special (object *who, object *op, int aflags)
2886{ 2886{
2887 if (INVOKE_OBJECT (BE_UNREADY, op, ARG_OBJECT (who), ARG_INT (aflags)) || INVOKE_OBJECT (UNREADY, who, ARG_OBJECT (op), ARG_INT (aflags)))
2888 return RESULT_INT (0);
2889
2887 object *tmp2; 2890 object *tmp2;
2888 2891
2889 CLEAR_FLAG(op, FLAG_APPLIED); 2892 CLEAR_FLAG (op, FLAG_APPLIED);
2890 switch(op->type) { 2893 switch (op->type)
2894 {
2891 case WEAPON: 2895 case WEAPON:
2892 new_draw_info_format(NDI_UNIQUE, 0, who, "You unwield %s.",query_name(op)); 2896 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwield %s.", query_name (op));
2893 2897
2894 (void) change_abil (who,op);
2895 if(QUERY_FLAG(who,FLAG_READY_WEAPON))
2896 CLEAR_FLAG(who,FLAG_READY_WEAPON);
2897 /* GROS: update the current_weapon_script field (used with script_attack for weapons) */
2898 who->current_weapon_script = NULL;
2899 who->current_weapon = NULL;
2900 clear_skill(who);
2901 break;
2902
2903 case SKILL: /* allows objects to impart skills */
2904 case SKILL_TOOL:
2905 if (op != who->chosen_skill) {
2906 LOG (llevError, "BUG: apply_special(): applied skill is not a chosen skill\n");
2907 }
2908 if (who->type==PLAYER) {
2909 if (who->contr->shoottype == range_skill)
2910 who->contr->shoottype = range_none;
2911 if ( ! op->invisible) {
2912 new_draw_info_format (NDI_UNIQUE, 0, who,
2913 "You stop using the %s.", query_name(op));
2914 } else {
2915 new_draw_info_format (NDI_UNIQUE, 0, who,
2916 "You can no longer use the skill: %s.",
2917 op->skill);
2918 }
2919 }
2920 (void) change_abil (who, op); 2898 (void) change_abil (who, op);
2899 if (QUERY_FLAG (who, FLAG_READY_WEAPON))
2900 CLEAR_FLAG (who, FLAG_READY_WEAPON);
2901 clear_skill (who);
2902 break;
2903
2904 case SKILL: /* allows objects to impart skills */
2905 case SKILL_TOOL:
2906 if (op != who->chosen_skill)
2907 {
2908 LOG (llevError, "BUG: apply_special(): applied skill is not a chosen skill\n");
2909 }
2910 if (who->type == PLAYER)
2911 {
2912 if (who->contr->shoottype == range_skill)
2913 who->contr->shoottype = range_none;
2914 if (!op->invisible)
2915 {
2916 new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op));
2917 }
2918 else
2919 {
2920 new_draw_info_format (NDI_UNIQUE, 0, who, "You can no longer use the skill: %s.", &op->skill);
2921 }
2922 }
2923 (void) change_abil (who, op);
2921 who->chosen_skill = NULL; 2924 who->chosen_skill = NULL;
2922 CLEAR_FLAG (who, FLAG_READY_SKILL); 2925 CLEAR_FLAG (who, FLAG_READY_SKILL);
2923 break; 2926 break;
2924 2927
2925 case ARMOUR: 2928 case ARMOUR:
2926 case HELMET: 2929 case HELMET:
2927 case SHIELD: 2930 case SHIELD:
2928 case RING: 2931 case RING:
2929 case BOOTS: 2932 case BOOTS:
2930 case GLOVES: 2933 case GLOVES:
2931 case AMULET: 2934 case AMULET:
2932 case GIRDLE: 2935 case GIRDLE:
2933 case BRACERS: 2936 case BRACERS:
2934 case CLOAK: 2937 case CLOAK:
2935 new_draw_info_format(NDI_UNIQUE, 0, who, "You unwear %s.",query_name(op)); 2938 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwear %s.", query_name (op));
2936 (void) change_abil (who,op); 2939 (void) change_abil (who, op);
2937 break; 2940 break;
2938 case LAMP: 2941 case LAMP:
2939 new_draw_info_format(NDI_UNIQUE, 0, who, "You turn off your %s.", 2942 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn off your %s.", &op->name);
2940 op->name);
2941 tmp2 = arch_to_object(op->other_arch); 2943 tmp2 = arch_to_object (op->other_arch);
2942 tmp2->x = op->x; 2944 tmp2->x = op->x;
2943 tmp2->y = op->y; 2945 tmp2->y = op->y;
2944 tmp2->map = op->map; 2946 tmp2->map = op->map;
2945 tmp2->below = op->below; 2947 tmp2->below = op->below;
2946 tmp2->above = op->above; 2948 tmp2->above = op->above;
2947 tmp2->stats.food = op->stats.food; 2949 tmp2->stats.food = op->stats.food;
2948 CLEAR_FLAG(tmp2, FLAG_APPLIED); 2950 CLEAR_FLAG (tmp2, FLAG_APPLIED);
2951
2949 if (QUERY_FLAG(op, FLAG_INV_LOCKED)) 2952 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
2950 SET_FLAG(tmp2, FLAG_INV_LOCKED); 2953 SET_FLAG (tmp2, FLAG_INV_LOCKED);
2954
2951 if (who->type == PLAYER) 2955 if (who->type == PLAYER)
2952 esrv_del_item(who->contr, (tag_t)op->count); 2956 esrv_del_item (who->contr, op->count);
2957
2953 remove_ob(op); 2958 remove_ob (op);
2954 free_object(op); 2959 free_object (op);
2955 insert_ob_in_ob(tmp2, who); 2960 insert_ob_in_ob (tmp2, who);
2956 fix_player(who); 2961 fix_player (who);
2957 if (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED)) { 2962 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2963 {
2958 if (who->type == PLAYER) { 2964 if (who->type == PLAYER)
2965 {
2959 new_draw_info(NDI_UNIQUE, 0,who, "Oops, it feels deadly cold!"); 2966 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
2960 SET_FLAG(tmp2, FLAG_KNOWN_CURSED); 2967 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
2961 } 2968 }
2962 } 2969 }
2963 if(who->type==PLAYER) 2970 if (who->type == PLAYER)
2964 esrv_send_item(who, tmp2); 2971 esrv_send_item (who, tmp2);
2965 return 1; /* otherwise, an attempt to drop causes problems */ 2972 return 1; /* otherwise, an attempt to drop causes problems */
2966 break; 2973 break;
2967 case BOW: 2974 case BOW:
2968 case WAND: 2975 case WAND:
2969 case ROD: 2976 case ROD:
2970 case HORN: 2977 case HORN:
2971 clear_skill(who); 2978 clear_skill (who);
2972 new_draw_info_format(NDI_UNIQUE, 0, who, "You unready %s.",query_name(op)); 2979 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2973 if(who->type==PLAYER) { 2980 if (who->type == PLAYER)
2981 {
2974 who->contr->shoottype = range_none; 2982 who->contr->shoottype = range_none;
2975 } else { 2983 }
2976 if (op->type == BOW) 2984 else
2985 {
2986 if (op->type == BOW)
2977 CLEAR_FLAG (who, FLAG_READY_BOW); 2987 CLEAR_FLAG (who, FLAG_READY_BOW);
2978 else 2988 else
2979 CLEAR_FLAG(who, FLAG_READY_RANGE); 2989 CLEAR_FLAG (who, FLAG_READY_RANGE);
2980 } 2990 }
2981 break; 2991 break;
2982 2992
2983 case BUILDER: 2993 case BUILDER:
2984 new_draw_info_format(NDI_UNIQUE, 0, who, "You unready %s.",query_name(op)); 2994 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2985 who->contr->shoottype = range_none; 2995 who->contr->shoottype = range_none;
2986 who->contr->ranges[ range_builder ] = NULL; 2996 who->contr->ranges[range_builder] = NULL;
2987 break; 2997 break;
2988 2998
2989 default: 2999 default:
2990 new_draw_info_format(NDI_UNIQUE, 0, who, "You unapply %s.",query_name(op)); 3000 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op));
2991 break; 3001 break;
2992 } 3002 }
2993 3003
2994 fix_player(who); 3004 fix_player (who);
2995 3005
2996 if ( ! (aflags & AP_NO_MERGE)) { 3006 if (!(aflags & AP_NO_MERGE))
3007 {
2997 object *tmp; 3008 object *tmp;
2998 3009
2999 tag_t del_tag = op->count;
3000 tmp = merge_ob (op, NULL); 3010 tmp = merge_ob (op, NULL);
3001 if (who->type == PLAYER) { 3011 if (who->type == PLAYER)
3002 if (tmp) { /* it was merged */ 3012 {
3013 if (tmp)
3014 { /* it was merged */
3003 esrv_del_item (who->contr, del_tag); 3015 esrv_del_item (who->contr, op->count);
3004 op = tmp; 3016 op = tmp;
3005 } 3017 }
3018
3006 esrv_send_item (who, op); 3019 esrv_send_item (who, op);
3007 } 3020 }
3008 } 3021 }
3009 return 0; 3022 return 0;
3010} 3023}
3011 3024
3012/** 3025/**
3013 * Returns the object that is using location 'loc'. 3026 * Returns the object that is using location 'loc'.
3014 * Note that 'start' is the first object to start examing - we 3027 * Note that 'start' is the first object to start examing - we
3021 * loc is the index into the array we are looking for a match. 3034 * loc is the index into the array we are looking for a match.
3022 * don't return invisible objects unless they are skill objects 3035 * don't return invisible objects unless they are skill objects
3023 * invisible other objects that use 3036 * invisible other objects that use
3024 * up body locations can be used as restrictions. 3037 * up body locations can be used as restrictions.
3025 */ 3038 */
3039object *
3026object *get_item_from_body_location(object *start, int loc) 3040get_item_from_body_location (object *start, int loc)
3027{ 3041{
3028 object *tmp; 3042 object *tmp;
3029 3043
3030 if (!start) return NULL; 3044 if (!start)
3031
3032 for (tmp=start; tmp; tmp=tmp->below)
3033 if (QUERY_FLAG(tmp, FLAG_APPLIED) && tmp->body_info[loc] &&
3034 (!tmp->invisible || tmp->type==SKILL)) return tmp;
3035
3036 return NULL; 3045 return NULL;
3046
3047 for (tmp = start; tmp; tmp = tmp->below)
3048 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->body_info[loc] && (!tmp->invisible || tmp->type == SKILL))
3049 return tmp;
3050
3051 return NULL;
3037} 3052}
3038 3053
3039 3054
3040 3055
3041/** 3056/**
3047 * Returns 0 on success, returns 1 if there is some problem. 3062 * Returns 0 on success, returns 1 if there is some problem.
3048 * if aflags is AP_PRINT, we instead print out waht to unapply 3063 * if aflags is AP_PRINT, we instead print out waht to unapply
3049 * instead of doing it. This is a lot less code than having 3064 * instead of doing it. This is a lot less code than having
3050 * another function that does just that. 3065 * another function that does just that.
3051 */ 3066 */
3067int
3052int unapply_for_ob(object *who, object *op, int aflags) 3068unapply_for_ob (object *who, object *op, int aflags)
3053{ 3069{
3054 int i; 3070 int i;
3055 object *tmp=NULL, *last; 3071 object *tmp = NULL, *last;
3056 3072
3057 /* If we are applying a shield or weapon, unapply any equipped shield 3073 /* If we are applying a shield or weapon, unapply any equipped shield
3058 * or weapons first - only allowed to use one weapon/shield at a time. 3074 * or weapons first - only allowed to use one weapon/shield at a time.
3059 */ 3075 */
3060 if (op->type == WEAPON || op->type == SHIELD) { 3076 if (op->type == WEAPON || op->type == SHIELD)
3077 {
3061 for (tmp=who->inv; tmp; tmp=tmp->below) { 3078 for (tmp = who->inv; tmp; tmp = tmp->below)
3079 {
3062 if (QUERY_FLAG(tmp, FLAG_APPLIED) && tmp->type == op->type) { 3080 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == op->type)
3063 if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || 3081 {
3064 (!QUERY_FLAG(tmp, FLAG_CURSED) && !QUERY_FLAG(tmp, FLAG_DAMNED))) { 3082 if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED)))
3083 {
3065 if (aflags & AP_PRINT) 3084 if (aflags & AP_PRINT)
3066 new_draw_info(NDI_UNIQUE, 0, who, query_name(tmp)); 3085 new_draw_info (NDI_UNIQUE, 0, who, query_name (tmp));
3067 else 3086 else
3068 unapply_special(who, tmp, aflags); 3087 unapply_special (who, tmp, aflags);
3069 } 3088 }
3070 else { 3089 else
3090 {
3071 /* In this case, we want to try and remove a cursed item. 3091 /* In this case, we want to try and remove a cursed item.
3072 * While we know it won't work, we want unapply_special to 3092 * While we know it won't work, we want unapply_special to
3073 * at least generate the message. 3093 * at least generate the message.
3074 */ 3094 */
3075 new_draw_info_format(NDI_UNIQUE, 0, who, 3095 new_draw_info_format (NDI_UNIQUE, 0, who, "No matter how hard you try, you just can't\nremove %s.", query_name (tmp));
3076 "No matter how hard you try, you just can't\nremove %s.", 3096 return 1;
3077 query_name(tmp)); 3097 }
3078 return 1;
3079 }
3080 3098
3099 }
3100 }
3081 } 3101 }
3082 }
3083 }
3084 3102
3085 for (i=0; i<NUM_BODY_LOCATIONS; i++) { 3103 for (i = 0; i < NUM_BODY_LOCATIONS; i++)
3104 {
3086 /* this used up a slot that we need to free */ 3105 /* this used up a slot that we need to free */
3087 if (op->body_info[i]) { 3106 if (op->body_info[i])
3107 {
3088 last = who->inv; 3108 last = who->inv;
3089 3109
3090 /* We do a while loop - may need to remove several items in order 3110 /* We do a while loop - may need to remove several items in order
3091 * to free up enough slots. 3111 * to free up enough slots.
3092 */ 3112 */
3093 while ((who->body_used[i] + op->body_info[i]) < 0) { 3113 while ((who->body_used[i] + op->body_info[i]) < 0)
3114 {
3094 tmp = get_item_from_body_location(last, i); 3115 tmp = get_item_from_body_location (last, i);
3095 if (!tmp) { 3116 if (!tmp)
3117 {
3096#if 0 3118#if 0
3097 /* Not a bug - we'll get this if the player has cursed items 3119 /* Not a bug - we'll get this if the player has cursed items
3098 * equipped. 3120 * equipped.
3099 */ 3121 */
3100 LOG(llevError,"Can't find object using location %d (%s) on %s\n", 3122 LOG (llevError, "Can't find object using location %d (%s) on %s\n", i, body_locations[i].save_name, who->name);
3101 i, body_locations[i].save_name, who->name);
3102#endif 3123#endif
3103 return 1; 3124 return 1;
3104 } 3125 }
3105 /* If we are just printing, we don't care about cursed status */ 3126 /* If we are just printing, we don't care about cursed status */
3106 if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || 3127 if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!(QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))))
3107 (!(QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)))) { 3128 {
3108 if (aflags & AP_PRINT) 3129 if (aflags & AP_PRINT)
3109 new_draw_info(NDI_UNIQUE, 0, who, query_name(tmp)); 3130 new_draw_info (NDI_UNIQUE, 0, who, query_name (tmp));
3110 else 3131 else
3111 unapply_special(who, tmp, aflags); 3132 unapply_special (who, tmp, aflags);
3112 } 3133 }
3113 else { 3134 else
3135 {
3114 /* Cursed item that we can't unequip - tell the player. 3136 /* Cursed item that we can't unequip - tell the player.
3115 * Note this could be annoying if this is just one of a few, 3137 * Note this could be annoying if this is just one of a few,
3116 * so it may not be critical (eg, putting on a ring and you have 3138 * so it may not be critical (eg, putting on a ring and you have
3117 * one cursed ring.) 3139 * one cursed ring.)
3118 */ 3140 */
3119 new_draw_info_format(NDI_UNIQUE, 0, who, "The %s just won't come off", query_name(tmp)); 3141 new_draw_info_format (NDI_UNIQUE, 0, who, "The %s just won't come off", query_name (tmp));
3120 } 3142 }
3121 last = tmp->below; 3143 last = tmp->below;
3122 } 3144 }
3123 /* if we got here, this slot is freed up - otherwise, if it wasn't freed up, the 3145 /* if we got here, this slot is freed up - otherwise, if it wasn't freed up, the
3124 * return in the !tmp would have kicked in. 3146 * return in the !tmp would have kicked in.
3125 */ 3147 */
3126 } /* if op is using this body location */ 3148 } /* if op is using this body location */
3127 } /* for body lcoations */ 3149 } /* for body lcoations */
3128 return 0; 3150 return 0;
3129} 3151}
3130 3152
3131/** 3153/**
3132 * Checks to see if 'who' can apply object 'op'. 3154 * Checks to see if 'who' can apply object 'op'.
3133 * Returns 0 if apply can be done without anything special. 3155 * Returns 0 if apply can be done without anything special.
3137 * is set, do we really are what the other flags may be?) 3159 * is set, do we really are what the other flags may be?)
3138 * 3160 *
3139 * See include/define.h for detailed description of the meaning of 3161 * See include/define.h for detailed description of the meaning of
3140 * these return values. 3162 * these return values.
3141 */ 3163 */
3164int
3142int can_apply_object(object *who, object *op) 3165can_apply_object (object *who, object *op)
3143{ 3166{
3167 if (INVOKE_OBJECT (CAN_BE_APPLIED, op, ARG_OBJECT (who)) || INVOKE_OBJECT (CAN_APPLY, who, ARG_OBJECT (op)))
3168 return RESULT_INT (0);
3169
3144 int i, retval=0; 3170 int i, retval = 0;
3145 object *tmp=NULL, *ws=NULL; 3171 object *tmp = NULL, *ws = NULL;
3146 3172
3147 /* Players have 2 'arm's, so they could in theory equip 2 shields or 3173 /* Players have 2 'arm's, so they could in theory equip 2 shields or
3148 * 2 weapons, but we don't want to let them do that. So if they are 3174 * 2 weapons, but we don't want to let them do that. So if they are
3149 * trying to equip a weapon or shield, see if they already have one 3175 * trying to equip a weapon or shield, see if they already have one
3150 * in place and store that way. 3176 * in place and store that way.
3151 */ 3177 */
3152 if (op->type == WEAPON || op->type == SHIELD) { 3178 if (op->type == WEAPON || op->type == SHIELD)
3179 {
3153 for (tmp=who->inv; tmp && !ws; tmp=tmp->below) { 3180 for (tmp = who->inv; tmp && !ws; tmp = tmp->below)
3181 {
3154 if (QUERY_FLAG(tmp, FLAG_APPLIED) && tmp->type == op->type) { 3182 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == op->type)
3183 {
3155 retval = CAN_APPLY_UNAPPLY; 3184 retval = CAN_APPLY_UNAPPLY;
3156 ws = tmp; 3185 ws = tmp;
3186 }
3187 }
3157 } 3188 }
3158 }
3159 }
3160
3161 3189
3190
3162 for (i=0; i<NUM_BODY_LOCATIONS; i++) { 3191 for (i = 0; i < NUM_BODY_LOCATIONS; i++)
3192 {
3163 if (op->body_info[i]) { 3193 if (op->body_info[i])
3194 {
3164 /* Item uses more slots than we have */ 3195 /* Item uses more slots than we have */
3165 if (FABS(op->body_info[i]) > who->body_info[i]) { 3196 if (FABS (op->body_info[i]) > who->body_info[i])
3197 {
3166 /* Could return now for efficiently - rest of info below isn' 3198 /* Could return now for efficiently - rest of info below isn'
3167 * really needed. 3199 * really needed.
3168 */ 3200 */
3169 retval |= CAN_APPLY_NEVER; 3201 retval |= CAN_APPLY_NEVER;
3202 }
3170 } else if ((who->body_used[i] + op->body_info[i]) < 0) { 3203 else if ((who->body_used[i] + op->body_info[i]) < 0)
3204 {
3171 /* in this case, equipping this would use more free spots than 3205 /* in this case, equipping this would use more free spots than
3172 * we have. 3206 * we have.
3173 */ 3207 */
3174 object *tmp1; 3208 object *tmp1;
3175 3209
3176 3210
3177 /* if we have an applied weapon/shield, and unapply it would free 3211 /* if we have an applied weapon/shield, and unapply it would free
3178 * enough slots to equip the new item, then just set this can 3212 * enough slots to equip the new item, then just set this can
3179 * continue. We don't care about the logic below - if you have 3213 * continue. We don't care about the logic below - if you have
3180 * shield equipped and try to equip another shield, there is only 3214 * shield equipped and try to equip another shield, there is only
3181 * one choice. However, the check for the number of body locations 3215 * one choice. However, the check for the number of body locations
3182 * does take into the account cases where what is being applied 3216 * does take into the account cases where what is being applied
3183 * may be two handed for example. 3217 * may be two handed for example.
3184 */ 3218 */
3185 if (ws) { 3219 if (ws)
3220 {
3186 if ((who->body_used[i] - ws->body_info[i] + op->body_info[i]) >=0) { 3221 if ((who->body_used[i] - ws->body_info[i] + op->body_info[i]) >= 0)
3187 retval |= CAN_APPLY_UNAPPLY; 3222 {
3188 continue; 3223 retval |= CAN_APPLY_UNAPPLY;
3189 } 3224 continue;
3190 } 3225 }
3226 }
3191 3227
3192 tmp1 = get_item_from_body_location(who->inv, i); 3228 tmp1 = get_item_from_body_location (who->inv, i);
3193 if (!tmp1) { 3229 if (!tmp1)
3230 {
3194#if 0 3231#if 0
3195 /* This is sort of an error, but happens a lot when old players 3232 /* This is sort of an error, but happens a lot when old players
3196 * join in with more stuff equipped than they are now allowed. 3233 * join in with more stuff equipped than they are now allowed.
3197 */ 3234 */
3198 LOG(llevError,"Can't find object using location %d on %s\n", 3235 LOG (llevError, "Can't find object using location %d on %s\n", i, who->name);
3199 i, who->name);
3200#endif 3236#endif
3201 retval |= CAN_APPLY_NEVER; 3237 retval |= CAN_APPLY_NEVER;
3202 } else { 3238 }
3239 else
3240 {
3203 /* need to unapply something. However, if this something 3241 /* need to unapply something. However, if this something
3204 * is different than we had found before, it means they need 3242 * is different than we had found before, it means they need
3205 * to apply multiple objects 3243 * to apply multiple objects
3206 */ 3244 */
3207 retval |= CAN_APPLY_UNAPPLY; 3245 retval |= CAN_APPLY_UNAPPLY;
3208 if (!tmp) tmp = tmp1; 3246 if (!tmp)
3209 else if (tmp != tmp1) { 3247 tmp = tmp1;
3210 retval |= CAN_APPLY_UNAPPLY_MULT; 3248 else if (tmp != tmp1)
3211 } 3249 {
3250 retval |= CAN_APPLY_UNAPPLY_MULT;
3251 }
3212 /* This object isn't using up all the slots, so there must 3252 /* This object isn't using up all the slots, so there must
3213 * be another. If so, and it the new item doesn't need all 3253 * be another. If so, and it the new item doesn't need all
3214 * the slots, the player then has a choice. 3254 * the slots, the player then has a choice.
3215 */ 3255 */
3216 if (((who->body_used[i] - tmp1->body_info[i]) != who->body_info[i]) && 3256 if (((who->body_used[i] - tmp1->body_info[i]) != who->body_info[i]) && (FABS (op->body_info[i]) < who->body_info[i]))
3217 (FABS(op->body_info[i]) < who->body_info[i]))
3218 retval |= CAN_APPLY_UNAPPLY_CHOICE; 3257 retval |= CAN_APPLY_UNAPPLY_CHOICE;
3219 3258
3220 /* Does unequippint 'tmp1' free up enough slots for this to be 3259 /* Does unequippint 'tmp1' free up enough slots for this to be
3221 * equipped? If not, there must be something else to unapply. 3260 * equipped? If not, there must be something else to unapply.
3222 */ 3261 */
3223 if ((who->body_used[i] + op->body_info[i] - tmp1->body_info[i]) < 0) 3262 if ((who->body_used[i] + op->body_info[i] - tmp1->body_info[i]) < 0)
3224 retval |= CAN_APPLY_UNAPPLY_MULT; 3263 retval |= CAN_APPLY_UNAPPLY_MULT;
3225 3264
3226 } 3265 }
3227 } /* if not enough free slots */ 3266 } /* if not enough free slots */
3228 } /* if this object uses location i */ 3267 } /* if this object uses location i */
3229 } /* for i -> num_body_locations loop */ 3268 } /* for i -> num_body_locations loop */
3230 3269
3231 /* Note that we don't check for FLAG_USE_ARMOUR - that should 3270 /* Note that we don't check for FLAG_USE_ARMOUR - that should
3232 * really be controlled by use of body locations. We do have 3271 * really be controlled by use of body locations. We do have
3233 * the weapon/shield checks, and the range checks for monsters, 3272 * the weapon/shield checks, and the range checks for monsters,
3234 * because you can't control those just by body location - bows, shields, 3273 * because you can't control those just by body location - bows, shields,
3235 * and weapons all use the same slot. Similar for horn/rod/wand - they 3274 * and weapons all use the same slot. Similar for horn/rod/wand - they
3236 * all use the same location. 3275 * all use the same location.
3237 */ 3276 */
3238 if (op->type == WEAPON && !QUERY_FLAG(who,FLAG_USE_WEAPON)) 3277 if (op->type == WEAPON && !QUERY_FLAG (who, FLAG_USE_WEAPON))
3239 retval |= CAN_APPLY_RESTRICTION;
3240 if (op->type == SHIELD && !QUERY_FLAG(who,FLAG_USE_SHIELD))
3241 retval |= CAN_APPLY_RESTRICTION;
3242
3243
3244 if (who->type != PLAYER) {
3245 if ((op->type == WAND || op->type == HORN || op->type==ROD)
3246 && !QUERY_FLAG(who, FLAG_USE_RANGE))
3247 retval |= CAN_APPLY_RESTRICTION;
3248 if (op->type == BOW && !QUERY_FLAG(who, FLAG_USE_BOW))
3249 retval |= CAN_APPLY_RESTRICTION; 3278 retval |= CAN_APPLY_RESTRICTION;
3250 if (op->type == RING && !QUERY_FLAG(who, FLAG_USE_RING)) 3279 if (op->type == SHIELD && !QUERY_FLAG (who, FLAG_USE_SHIELD))
3251 retval |= CAN_APPLY_RESTRICTION; 3280 retval |= CAN_APPLY_RESTRICTION;
3252 if (op->type == BOW && !QUERY_FLAG(who, FLAG_USE_BOW)) 3281
3282
3283 if (who->type != PLAYER)
3284 {
3285 if ((op->type == WAND || op->type == HORN || op->type == ROD) && !QUERY_FLAG (who, FLAG_USE_RANGE))
3253 retval |= CAN_APPLY_RESTRICTION; 3286 retval |= CAN_APPLY_RESTRICTION;
3287 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW))
3288 retval |= CAN_APPLY_RESTRICTION;
3289 if (op->type == RING && !QUERY_FLAG (who, FLAG_USE_RING))
3290 retval |= CAN_APPLY_RESTRICTION;
3291 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW))
3292 retval |= CAN_APPLY_RESTRICTION;
3254 } 3293 }
3255 return retval; 3294 return retval;
3256} 3295}
3257 3296
3258 3297
3259 3298
3260/** 3299/**
3261 * who is the object using the object. It can be a monster. 3300 * who is the object using the object. It can be a monster.
3262 * op is the object they are using. op is an equipment type item, 3301 * op is the object they are using. op is an equipment type item,
3263 * eg, one which you put on and keep on for a while, and not something 3302 * eg, one which you put on and keep on for a while, and not something
3277 * 3316 *
3278 * Usage example: apply_special (who, op, AP_UNAPPLY | AP_IGNORE_CURSE) 3317 * Usage example: apply_special (who, op, AP_UNAPPLY | AP_IGNORE_CURSE)
3279 * 3318 *
3280 * apply_special() doesn't check for unpaid items. 3319 * apply_special() doesn't check for unpaid items.
3281 */ 3320 */
3321int
3282int apply_special (object *who, object *op, int aflags) 3322apply_special (object *who, object *op, int aflags)
3283{ 3323{
3284 int basic_flag = aflags & AP_BASIC_FLAGS; 3324 int basic_flag = aflags & AP_BASIC_FLAGS;
3285 object *tmp, *tmp2, *skop=NULL; 3325 object *tmp, *tmp2, *skop = NULL;
3286 int i; 3326 int i;
3287 3327
3288 if(who==NULL) { 3328 if (who == NULL)
3329 {
3289 LOG(llevError,"apply_special() from object without environment.\n"); 3330 LOG (llevError, "apply_special() from object without environment.\n");
3290 return 1; 3331 return 1;
3291 } 3332 }
3292 3333
3293 if(op->env!=who) 3334 if (op->env != who)
3294 return 1; /* op is not in inventory */ 3335 return 1; /* op is not in inventory */
3295 3336
3296 /* trying to unequip op */ 3337 /* trying to unequip op */
3297 if (QUERY_FLAG(op,FLAG_APPLIED)) { 3338 if (QUERY_FLAG (op, FLAG_APPLIED))
3339 {
3298 /* always apply, so no reason to unapply */ 3340 /* always apply, so no reason to unapply */
3299 if (basic_flag == AP_APPLY) return 0; 3341 if (basic_flag == AP_APPLY)
3342 return 0;
3300 3343
3301 if ( ! (aflags & AP_IGNORE_CURSE) 3344 if (!(aflags & AP_IGNORE_CURSE) && (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)))
3302 && (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED))) { 3345 {
3303 new_draw_info_format(NDI_UNIQUE, 0, who, 3346 new_draw_info_format (NDI_UNIQUE, 0, who, "No matter how hard you try, you just can't\nremove %s.", query_name (op));
3304 "No matter how hard you try, you just can't\nremove %s.",
3305 query_name(op));
3306 return 1; 3347 return 1;
3307 } 3348 }
3308 return unapply_special(who, op, aflags); 3349 return unapply_special (who, op, aflags);
3309 } 3350 }
3310 3351
3311 if (basic_flag == AP_UNAPPLY) return 0; 3352 if (basic_flag == AP_UNAPPLY)
3353 return 0;
3312 3354
3313 i = can_apply_object(who, op); 3355 i = can_apply_object (who, op);
3314 3356
3315 /* Can't just apply this object. Lets see what not and what to do */ 3357 /* Can't just apply this object. Lets see what not and what to do */
3316 if (i) { 3358 if (i)
3359 {
3317 if (i & CAN_APPLY_NEVER) { 3360 if (i & CAN_APPLY_NEVER)
3361 {
3318 new_draw_info_format(NDI_UNIQUE, 0, who, "You don't have the body to use a %s\n", query_name(op)); 3362 new_draw_info_format (NDI_UNIQUE, 0, who, "You don't have the body to use a %s\n", query_name (op));
3319 return 1; 3363 return 1;
3364 }
3320 } else if (i & CAN_APPLY_RESTRICTION) { 3365 else if (i & CAN_APPLY_RESTRICTION)
3366 {
3321 new_draw_info_format(NDI_UNIQUE, 0, who, "You have a prohibition against using a %s\n", query_name(op)); 3367 new_draw_info_format (NDI_UNIQUE, 0, who, "You have a prohibition against using a %s\n", query_name (op));
3322 return 1; 3368 return 1;
3323 } 3369 }
3324 if (who->type != PLAYER) { 3370 if (who->type != PLAYER)
3371 {
3325 /* Some error, so don't try to equip something more */ 3372 /* Some error, so don't try to equip something more */
3326 if (unapply_for_ob(who, op, aflags)) return 1; 3373 if (unapply_for_ob (who, op, aflags))
3327 } else { 3374 return 1;
3328 if (who->contr->unapply == unapply_never || 3375 }
3329 (i & CAN_APPLY_UNAPPLY_CHOICE && who->contr->unapply == unapply_nochoice)) { 3376 else
3377 {
3378 if (who->contr->unapply == unapply_never || (i & CAN_APPLY_UNAPPLY_CHOICE && who->contr->unapply == unapply_nochoice))
3379 {
3330 new_draw_info(NDI_UNIQUE, 0, who, "You need to unapply some item(s):"); 3380 new_draw_info (NDI_UNIQUE, 0, who, "You need to unapply some item(s):");
3331 unapply_for_ob(who, op, AP_PRINT); 3381 unapply_for_ob (who, op, AP_PRINT);
3332 return 1; 3382 return 1;
3333 } 3383 }
3334 else if (who->contr->unapply == unapply_always || !(i & CAN_APPLY_UNAPPLY_CHOICE)) { 3384 else if (who->contr->unapply == unapply_always || !(i & CAN_APPLY_UNAPPLY_CHOICE))
3385 {
3335 i = unapply_for_ob(who, op, aflags); 3386 i = unapply_for_ob (who, op, aflags);
3336 if (i) return 1; 3387 if (i)
3388 return 1;
3389 }
3390 }
3337 } 3391 }
3338 }
3339 }
3340 if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) { 3392 if (op->skill && op->type != SKILL && op->type != SKILL_TOOL)
3393 {
3341 skop=find_skill_by_name(who, op->skill); 3394 skop = find_skill_by_name (who, op->skill);
3342 if (!skop) { 3395 if (!skop)
3396 {
3343 new_draw_info_format(NDI_UNIQUE, 0, who, "You need the %s skill to use this item!", op->skill); 3397 new_draw_info_format (NDI_UNIQUE, 0, who, "You need the %s skill to use this item!", &op->skill);
3344 return 1; 3398 return 1;
3345 } else { 3399 }
3400 else
3401 {
3346 /* While experience will be credited properly, we want to change the 3402 /* While experience will be credited properly, we want to change the
3347 * skill so that the dam and wc get updated 3403 * skill so that the dam and wc get updated
3348 */ 3404 */
3349 change_skill(who, skop, 0); 3405 change_skill (who, skop, 0);
3350 } 3406 }
3407 }
3408
3409 if (who->type == PLAYER && op->item_power && (op->item_power + who->contr->item_power) > (settings.item_power_factor * who->level))
3351 } 3410 {
3352
3353 if (who->type == PLAYER && op->item_power &&
3354 (op->item_power + who->contr->item_power) > (settings.item_power_factor * who->level)) {
3355 new_draw_info(NDI_UNIQUE, 0, who, "Equipping that combined with other items would consume your soul!"); 3411 new_draw_info (NDI_UNIQUE, 0, who, "Equipping that combined with other items would consume your soul!");
3356 return 1; 3412 return 1;
3357 } 3413 }
3358
3359 3414
3415
3360 /* Ok. We are now at the state where we can apply the new object. 3416 /* Ok. We are now at the state where we can apply the new object.
3361 * Note that we don't have the checks for can_use_... 3417 * Note that we don't have the checks for can_use_...
3362 * below - that is already taken care of by can_apply_object. 3418 * below - that is already taken care of by can_apply_object.
3363 */ 3419 */
3364
3365 3420
3421
3366 if(op->nrof > 1) 3422 if (op->nrof > 1)
3367 tmp = get_split_ob(op,op->nrof - 1); 3423 tmp = get_split_ob (op, op->nrof - 1);
3368 else 3424 else
3369 tmp = NULL; 3425 tmp = NULL;
3370 3426
3427 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op)))
3428 return RESULT_INT (0);
3429
3371 switch(op->type) { 3430 switch (op->type)
3431 {
3372 case WEAPON: 3432 case WEAPON:
3373 if (!check_weapon_power(who, op->last_eat)) { 3433 if (!check_weapon_power (who, op->last_eat))
3374 new_draw_info(NDI_UNIQUE, 0,who, 3434 {
3375 "That weapon is too powerful for you to use."); 3435 new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use.");
3376 new_draw_info(NDI_UNIQUE, 0, who, "It would consume your soul!."); 3436 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!.");
3377 if(tmp!=NULL) 3437 if (tmp != NULL)
3378 (void) insert_ob_in_ob(tmp,who); 3438 (void) insert_ob_in_ob (tmp, who);
3379 return 1; 3439 return 1;
3380 } 3440 }
3381 if( op->level && (strncmp(op->name,who->name,strlen(who->name)))) { 3441 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3442 {
3382 /* if the weapon does not have the name as the character, can't use it. */ 3443 /* if the weapon does not have the name as the character, can't use it. */
3383 /* (Ragnarok's sword attempted to be used by Foo: won't work) */ 3444 /* (Ragnarok's sword attempted to be used by Foo: won't work) */
3384 new_draw_info(NDI_UNIQUE, 0,who,"The weapon does not recognize you as its owner."); 3445 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3385 if(tmp!=NULL) 3446 if (tmp != NULL)
3386 (void) insert_ob_in_ob(tmp,who); 3447 (void) insert_ob_in_ob (tmp, who);
3387 return 1; 3448 return 1;
3388 } 3449 }
3389 SET_FLAG(op, FLAG_APPLIED); 3450 SET_FLAG (op, FLAG_APPLIED);
3390 3451
3391 if (skop) change_skill(who, skop, 1); 3452 if (skop)
3453 change_skill (who, skop, 1);
3392 if(!QUERY_FLAG(who,FLAG_READY_WEAPON)) 3454 if (!QUERY_FLAG (who, FLAG_READY_WEAPON))
3393 SET_FLAG(who, FLAG_READY_WEAPON); 3455 SET_FLAG (who, FLAG_READY_WEAPON);
3394 3456
3395 new_draw_info_format(NDI_UNIQUE, 0, who, "You wield %s.",query_name(op)); 3457 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op));
3396 3458
3397 (void) change_abil (who,op); 3459 (void) change_abil (who, op);
3398 /* GROS: update the current_weapon_script field (used with EVENT_ATTACK for weapons) */
3399 /*if ((evt = find_event(op, EVENT_ATTACK)) != NULL) {
3400 LOG(llevDebug, "Scripting Weapon wielded\n");
3401 if (who->current_weapon_script) free_string(who->current_weapon_script);
3402 who->current_weapon_script=add_string(query_name(op));
3403 }
3404 who->current_weapon = op;*/
3405 break; 3460 break;
3406 3461
3407 case ARMOUR: 3462 case ARMOUR:
3408 case HELMET: 3463 case HELMET:
3409 case SHIELD: 3464 case SHIELD:
3410 case BOOTS: 3465 case BOOTS:
3411 case GLOVES: 3466 case GLOVES:
3412 case GIRDLE: 3467 case GIRDLE:
3413 case BRACERS: 3468 case BRACERS:
3414 case CLOAK: 3469 case CLOAK:
3415 case RING: 3470 case RING:
3416 case AMULET: 3471 case AMULET:
3417 SET_FLAG(op, FLAG_APPLIED); 3472 SET_FLAG (op, FLAG_APPLIED);
3418 new_draw_info_format(NDI_UNIQUE, 0, who, "You wear %s.",query_name(op)); 3473 new_draw_info_format (NDI_UNIQUE, 0, who, "You wear %s.", query_name (op));
3419 (void) change_abil (who,op); 3474 (void) change_abil (who, op);
3420 break; 3475 break;
3421 case LAMP: 3476 case LAMP:
3422 if (op->stats.food < 1) { 3477 if (op->stats.food < 1)
3478 {
3423 new_draw_info_format(NDI_UNIQUE, 0, who, "Your %s is out of" 3479 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name);
3424 " fuel!", op->name); 3480 return 1;
3425 return 1; 3481 }
3426 }
3427 new_draw_info_format(NDI_UNIQUE, 0, who, "You turn on your %s.", 3482 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name);
3428 op->name);
3429 tmp2 = arch_to_object(op->other_arch); 3483 tmp2 = arch_to_object (op->other_arch);
3430 tmp2->stats.food = op->stats.food; 3484 tmp2->stats.food = op->stats.food;
3431 SET_FLAG(tmp2, FLAG_APPLIED); 3485 SET_FLAG (tmp2, FLAG_APPLIED);
3432 if (QUERY_FLAG(op, FLAG_INV_LOCKED)) 3486 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
3433 SET_FLAG(tmp2, FLAG_INV_LOCKED); 3487 SET_FLAG (tmp2, FLAG_INV_LOCKED);
3434 insert_ob_in_ob(tmp2, who); 3488 insert_ob_in_ob (tmp2, who);
3435 3489
3436 /* Remove the old lantern */ 3490 /* Remove the old lantern */
3437 if (who->type == PLAYER) 3491 if (who->type == PLAYER)
3438 esrv_del_item(who->contr, (tag_t)op->count); 3492 esrv_del_item (who->contr, op->count);
3493
3439 remove_ob(op); 3494 remove_ob (op);
3440 free_object(op); 3495 free_object (op);
3441 3496
3442 /* insert the portion that was split off */ 3497 /* insert the portion that was split off */
3443 if(tmp!=NULL) { 3498 if (tmp != NULL)
3499 {
3444 (void) insert_ob_in_ob(tmp,who); 3500 (void) insert_ob_in_ob (tmp, who);
3445 if(who->type==PLAYER) 3501 if (who->type == PLAYER)
3446 esrv_send_item(who, tmp); 3502 esrv_send_item (who, tmp);
3447 } 3503 }
3448 fix_player(who); 3504 fix_player (who);
3449 if (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED)) { 3505 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
3506 {
3450 if (who->type == PLAYER) { 3507 if (who->type == PLAYER)
3508 {
3451 new_draw_info(NDI_UNIQUE, 0,who, "Oops, it feels deadly cold!"); 3509 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
3452 SET_FLAG(tmp2, FLAG_KNOWN_CURSED); 3510 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
3453 } 3511 }
3454 } 3512 }
3455 if(who->type==PLAYER) 3513 if (who->type == PLAYER)
3456 esrv_send_item(who, tmp2); 3514 esrv_send_item (who, tmp2);
3457 return 0; 3515 return 0;
3458 break; 3516 break;
3459 3517
3460 /* this part is needed for skill-tools */ 3518 /* this part is needed for skill-tools */
3461 case SKILL: 3519 case SKILL:
3462 case SKILL_TOOL: 3520 case SKILL_TOOL:
3463 if (who->chosen_skill) { 3521 if (who->chosen_skill)
3522 {
3464 LOG (llevError, "BUG: apply_special(): can't apply two skills\n"); 3523 LOG (llevError, "BUG: apply_special(): can't apply two skills\n");
3465 return 1; 3524 return 1;
3466 } 3525 }
3467 if (who->type == PLAYER) { 3526 if (who->type == PLAYER)
3527 {
3468 who->contr->shoottype = range_skill; 3528 who->contr->shoottype = range_skill;
3469 who->contr->ranges[range_skill] = op; 3529 who->contr->ranges[range_skill] = op;
3470 if ( ! op->invisible) { 3530 if (!op->invisible)
3531 {
3471 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", 3532 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op));
3472 query_name (op)); 3533 new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill);
3473 new_draw_info_format (NDI_UNIQUE, 0, who, 3534 }
3474 "You can now use the skill: %s.", 3535 else
3475 op->skill); 3536 {
3476 } else { 3537 new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name);
3477 new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", 3538 }
3478 op->skill? op->skill:op->name); 3539 }
3479 }
3480 }
3481 SET_FLAG (op, FLAG_APPLIED); 3540 SET_FLAG (op, FLAG_APPLIED);
3482 (void) change_abil (who, op); 3541 (void) change_abil (who, op);
3483 who->chosen_skill = op; 3542 who->chosen_skill = op;
3484 SET_FLAG (who, FLAG_READY_SKILL); 3543 SET_FLAG (who, FLAG_READY_SKILL);
3485 break; 3544 break;
3486 3545
3487 case BOW: 3546 case BOW:
3488 if (!check_weapon_power(who, op->last_eat)) { 3547 if (!check_weapon_power (who, op->last_eat))
3489 new_draw_info(NDI_UNIQUE, 0, who, 3548 {
3490 "That item is too powerful for you to use."); 3549 new_draw_info (NDI_UNIQUE, 0, who, "That item is too powerful for you to use.");
3491 new_draw_info(NDI_UNIQUE, 0, who, "It would consume your soul!."); 3550 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!.");
3492 if(tmp != NULL) 3551 if (tmp != NULL)
3493 (void)insert_ob_in_ob(tmp,who); 3552 (void) insert_ob_in_ob (tmp, who);
3494 return 1; 3553 return 1;
3495 } 3554 }
3496 if( op->level && (strncmp(op->name,who->name,strlen(who->name)))) { 3555 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3497 new_draw_info(NDI_UNIQUE, 0, who, 3556 {
3498 "The weapon does not recognize you as its owner."); 3557 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3499 if(tmp != NULL) 3558 if (tmp != NULL)
3500 (void)insert_ob_in_ob(tmp,who); 3559 (void) insert_ob_in_ob (tmp, who);
3501 return 1; 3560 return 1;
3502 } 3561 }
3503 /*FALLTHROUGH*/ 3562 /*FALLTHROUGH*/ case WAND:
3504 case WAND: 3563 case ROD:
3505 case ROD: 3564 case HORN:
3506 case HORN:
3507 /* check for skill, alter player status */ 3565 /* check for skill, alter player status */
3508 SET_FLAG(op, FLAG_APPLIED); 3566 SET_FLAG (op, FLAG_APPLIED);
3509 if (skop) change_skill(who, skop, 0); 3567 if (skop)
3568 change_skill (who, skop, 0);
3510 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name(op)); 3569 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op));
3511 3570
3512 if(who->type==PLAYER) { 3571 if (who->type == PLAYER)
3513 if (op->type == BOW) { 3572 {
3573 if (op->type == BOW)
3574 {
3514 (void)change_abil(who, op); 3575 (void) change_abil (who, op);
3515 new_draw_info_format (NDI_UNIQUE, 0, who, 3576 new_draw_info_format (NDI_UNIQUE, 0, who,
3516 "You will now fire %s with %s.", 3577 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op));
3517 op->race ? op->race : "nothing", query_name(op));
3518 who->contr->shoottype = range_bow; 3578 who->contr->shoottype = range_bow;
3519 } else { 3579 }
3580 else
3581 {
3520 who->contr->shoottype = range_misc; 3582 who->contr->shoottype = range_misc;
3521 } 3583 }
3522 } else { 3584 }
3523 if (op->type == BOW) 3585 else
3586 {
3587 if (op->type == BOW)
3524 SET_FLAG (who, FLAG_READY_BOW); 3588 SET_FLAG (who, FLAG_READY_BOW);
3525 else 3589 else
3526 SET_FLAG (who, FLAG_READY_RANGE); 3590 SET_FLAG (who, FLAG_READY_RANGE);
3527 } 3591 }
3528 break; 3592 break;
3529 3593
3530 case BUILDER: 3594 case BUILDER:
3531 if ( who->contr->ranges[ range_builder ] ) 3595 if (who->contr->ranges[range_builder])
3532 unapply_special( who, who->contr->ranges[ range_builder ], 0 ); 3596 unapply_special (who, who->contr->ranges[range_builder], 0);
3533 who->contr->shoottype = range_builder; 3597 who->contr->shoottype = range_builder;
3534 who->contr->ranges[ range_builder ] = op; 3598 who->contr->ranges[range_builder] = op;
3535 new_draw_info_format( NDI_UNIQUE, 0, who, "You ready your %s.", query_name( op ) ); 3599 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op));
3536 break; 3600 break;
3537 3601
3538 default: 3602 default:
3539 new_draw_info_format(NDI_UNIQUE, 0, who, "You apply %s.",query_name(op)); 3603 new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op));
3540 } /* end of switch op->type */ 3604 } /* end of switch op->type */
3541 3605
3542 SET_FLAG(op, FLAG_APPLIED); 3606 SET_FLAG (op, FLAG_APPLIED);
3543 3607
3544 if(tmp!=NULL) 3608 if (tmp != NULL)
3545 tmp = insert_ob_in_ob(tmp,who); 3609 tmp = insert_ob_in_ob (tmp, who);
3546 3610
3547 fix_player(who); 3611 fix_player (who);
3548 3612
3549 /* We exclude spell casting objects. The fire code will set the 3613 /* We exclude spell casting objects. The fire code will set the
3550 * been applied flag when they are used - until that point, 3614 * been applied flag when they are used - until that point,
3551 * you don't know anything about them. 3615 * you don't know anything about them.
3552 */ 3616 */
3553 if (who->type == PLAYER && op->type!=WAND && op->type!=HORN && 3617 if (who->type == PLAYER && op->type != WAND && op->type != HORN && op->type != ROD)
3554 op->type!=ROD)
3555 SET_FLAG(op,FLAG_BEEN_APPLIED); 3618 SET_FLAG (op, FLAG_BEEN_APPLIED);
3556 3619
3557 if (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED)) { 3620 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
3621 {
3558 if (who->type == PLAYER) { 3622 if (who->type == PLAYER)
3623 {
3559 new_draw_info(NDI_UNIQUE, 0,who, "Oops, it feels deadly cold!"); 3624 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
3560 SET_FLAG(op,FLAG_KNOWN_CURSED); 3625 SET_FLAG (op, FLAG_KNOWN_CURSED);
3561 } 3626 }
3562 } 3627 }
3563 if(who->type==PLAYER) { 3628 if (who->type == PLAYER)
3629 {
3564 /* if multiple objects were applied, update both slots */ 3630 /* if multiple objects were applied, update both slots */
3565 if (tmp) 3631 if (tmp)
3566 esrv_send_item(who, tmp); 3632 esrv_send_item (who, tmp);
3567 esrv_send_item(who, op); 3633 esrv_send_item (who, op);
3568 } 3634 }
3569 return 0; 3635 return 0;
3570} 3636}
3571 3637
3572 3638
3639int
3573int monster_apply_special (object *who, object *op, int aflags) 3640monster_apply_special (object *who, object *op, int aflags)
3574{ 3641{
3575 if (QUERY_FLAG (op, FLAG_UNPAID) && ! QUERY_FLAG (op, FLAG_APPLIED)) 3642 if (QUERY_FLAG (op, FLAG_UNPAID) && !QUERY_FLAG (op, FLAG_APPLIED))
3576 return 1; 3643 return 1;
3577 return apply_special (who, op, aflags); 3644 return apply_special (who, op, aflags);
3578} 3645}
3579 3646
3580/** 3647/**
3581 * Map was just loaded, handle op's initialisation. 3648 * Map was just loaded, handle op's initialisation.
3582 * 3649 *
3583 * Generates shop floor's item, and treasures. 3650 * Generates shop floor's item, and treasures.
3584 */ 3651 */
3652int
3585int auto_apply (object *op) { 3653auto_apply (object *op)
3654{
3586 object *tmp = NULL, *tmp2; 3655 object *tmp = NULL, *tmp2;
3587 int i; 3656 int i;
3588 3657
3589 switch(op->type) { 3658 switch (op->type)
3659 {
3590 case SHOP_FLOOR: 3660 case SHOP_FLOOR:
3591 if (!HAS_RANDOM_ITEMS(op)) return 0; 3661 if (!HAS_RANDOM_ITEMS (op))
3592 do { 3662 return 0;
3593 i=10; /* let's give it 10 tries */ 3663 do
3664 {
3665 i = 10; /* let's give it 10 tries */
3594 while((tmp=generate_treasure(op->randomitems, 3666 while ((tmp = generate_treasure (op->randomitems,
3595 op->stats.exp?(int)op->stats.exp:MAX(op->map->difficulty, 5)))==NULL&&--i); 3667 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i);
3596 if(tmp==NULL) 3668 if (tmp == NULL)
3597 return 0; 3669 return 0;
3598 if(QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)) { 3670 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
3599 free_object(tmp); 3671 {
3600 tmp = NULL; 3672 free_object (tmp);
3601 } 3673 tmp = NULL;
3602 } while(!tmp); 3674 }
3675 }
3676 while (!tmp);
3603 tmp->x=op->x; 3677 tmp->x = op->x;
3604 tmp->y=op->y; 3678 tmp->y = op->y;
3605 SET_FLAG(tmp,FLAG_UNPAID); 3679 SET_FLAG (tmp, FLAG_UNPAID);
3606 insert_ob_in_map(tmp,op->map,NULL,0); 3680 insert_ob_in_map (tmp, op->map, NULL, 0);
3607 CLEAR_FLAG(op,FLAG_AUTO_APPLY); 3681 CLEAR_FLAG (op, FLAG_AUTO_APPLY);
3608 identify(tmp); 3682 identify (tmp);
3609 break; 3683 break;
3610 3684
3611 case TREASURE: 3685 case TREASURE:
3612 if (QUERY_FLAG(op,FLAG_IS_A_TEMPLATE)) 3686 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
3613 return 0; 3687 return 0;
3614 while ((op->stats.hp--)>0) 3688 while ((op->stats.hp--) > 0)
3615 create_treasure(op->randomitems, op, op->map?GT_ENVIRONMENT:0, 3689 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0,
3616 op->stats.exp ? (int)op->stats.exp : 3690 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3617 op->map == NULL ? 14: op->map->difficulty,0);
3618 3691
3619 /* If we generated an object and put it in this object inventory, 3692 /* If we generated an object and put it in this object inventory,
3620 * move it to the parent object as the current object is about 3693 * move it to the parent object as the current object is about
3621 * to disappear. An example of this item is the random_* stuff 3694 * to disappear. An example of this item is the random_* stuff
3622 * that is put inside other objects. 3695 * that is put inside other objects.
3623 */ 3696 */
3624 for (tmp=op->inv; tmp; tmp=tmp2) { 3697 for (tmp = op->inv; tmp; tmp = tmp2)
3625 tmp2 = tmp->below; 3698 {
3626 remove_ob(tmp); 3699 tmp2 = tmp->below;
3627 if (op->env) insert_ob_in_ob(tmp, op->env); 3700 remove_ob (tmp);
3628 else free_object(tmp); 3701 if (op->env)
3702 insert_ob_in_ob (tmp, op->env);
3703 else
3704 free_object (tmp);
3705 }
3706 remove_ob (op);
3707 free_object (op);
3708 break;
3629 } 3709 }
3630 remove_ob(op);
3631 free_object(op);
3632 break;
3633 }
3634 return tmp ? 1 : 0; 3710 return tmp ? 1 : 0;
3635} 3711}
3636 3712
3637/** 3713/**
3638 * fix_auto_apply goes through the entire map (only the first time 3714 * fix_auto_apply goes through the entire map (only the first time
3639 * when an original map is loaded) and performs special actions for 3715 * when an original map is loaded) and performs special actions for
3640 * certain objects (most initialization of chests and creation of 3716 * certain objects (most initialization of chests and creation of
3641 * treasures and stuff). Calls auto_apply if appropriate. 3717 * treasures and stuff). Calls auto_apply if appropriate.
3642 */ 3718 */
3643 3719void
3644void fix_auto_apply(mapstruct *m) { 3720fix_auto_apply (maptile *m)
3721{
3645 object *tmp,*above=NULL; 3722 object *tmp, *above = NULL;
3646 int x,y; 3723 int x, y;
3647 3724
3648 if(m==NULL) return; 3725 if (m == NULL)
3726 return;
3649 3727
3650 for(x=0;x<MAP_WIDTH(m);x++) 3728 for (x = 0; x < MAP_WIDTH (m); x++)
3651 for(y=0;y<MAP_HEIGHT(m);y++) 3729 for (y = 0; y < MAP_HEIGHT (m); y++)
3652 for(tmp=get_map_ob(m,x,y);tmp!=NULL;tmp=above) { 3730 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = above)
3653 above=tmp->above; 3731 {
3732 above = tmp->above;
3654 3733
3655 if (tmp->inv) { 3734 if (tmp->inv)
3735 {
3656 object *invtmp, *invnext; 3736 object *invtmp, *invnext;
3657 3737
3658 for (invtmp=tmp->inv; invtmp != NULL; invtmp = invnext) { 3738 for (invtmp = tmp->inv; invtmp != NULL; invtmp = invnext)
3659 invnext = invtmp->below; 3739 {
3740 invnext = invtmp->below;
3660 3741
3661 if(QUERY_FLAG(invtmp,FLAG_AUTO_APPLY)) 3742 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY))
3662 auto_apply(invtmp); 3743 auto_apply (invtmp);
3663 else if(invtmp->type==TREASURE && HAS_RANDOM_ITEMS(invtmp)) { 3744 else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS (invtmp))
3664 while ((invtmp->stats.hp--)>0) 3745 {
3665 create_treasure(invtmp->randomitems, invtmp, 0, 3746 while ((invtmp->stats.hp--) > 0)
3666 m->difficulty,0); 3747 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3667 invtmp->randomitems = NULL; 3748
3668 } 3749 invtmp->randomitems = NULL;
3669 else if (invtmp && invtmp->arch && 3750 }
3670 invtmp->type!=TREASURE && 3751 else if (invtmp && invtmp->arch
3671 invtmp->type != SPELL && 3752 && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS && HAS_RANDOM_ITEMS (invtmp))
3672 invtmp->type != CLASS && 3753 {
3673 HAS_RANDOM_ITEMS(invtmp)) { 3754 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3674 create_treasure(invtmp->randomitems, invtmp, 0,
3675 m->difficulty,0);
3676 /* Need to clear this so that we never try to create 3755 /* Need to clear this so that we never try to create
3677 * treasure again for this object 3756 * treasure again for this object
3678 */ 3757 */
3679 invtmp->randomitems = NULL; 3758 invtmp->randomitems = NULL;
3680 } 3759 }
3681 } 3760 }
3682 /* This is really temporary - the code at the bottom will 3761 /* This is really temporary - the code at the bottom will
3683 * also set randomitems to null. The problem is there are bunches 3762 * also set randomitems to null. The problem is there are bunches
3684 * of maps/players already out there with items that have spells 3763 * of maps/players already out there with items that have spells
3685 * which haven't had the randomitems set to null yet. 3764 * which haven't had the randomitems set to null yet.
3686 * MSW 2004-05-13 3765 * MSW 2004-05-13
3687 * 3766 *
3688 * And if it's a spellbook, it's better to set randomitems to NULL too, 3767 * And if it's a spellbook, it's better to set randomitems to NULL too,
3689 * else you get two spells in the book ^_- 3768 * else you get two spells in the book ^_-
3690 * Ryo 2004-08-16 3769 * Ryo 2004-08-16
3691 */ 3770 */
3692 if (tmp->type == WAND || tmp->type == ROD || tmp->type == SCROLL || 3771 if (tmp->type == WAND || tmp->type == ROD || tmp->type == SCROLL
3693 tmp->type == HORN || tmp->type == FIREWALL || tmp->type == POTION || 3772 || tmp->type == HORN || tmp->type == FIREWALL || tmp->type == POTION || tmp->type == ALTAR || tmp->type == SPELLBOOK)
3694 tmp->type == ALTAR || tmp->type == SPELLBOOK)
3695 tmp->randomitems = NULL; 3773 tmp->randomitems = NULL;
3696 3774
3697 } 3775 }
3698 3776
3699 if(QUERY_FLAG(tmp,FLAG_AUTO_APPLY)) 3777 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY))
3700 auto_apply(tmp); 3778 auto_apply (tmp);
3701 else if((tmp->type==TREASURE || (tmp->type==CONTAINER))&& HAS_RANDOM_ITEMS(tmp)) { 3779 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && HAS_RANDOM_ITEMS (tmp))
3780 {
3702 while ((tmp->stats.hp--)>0) 3781 while ((tmp->stats.hp--) > 0)
3703 create_treasure(tmp->randomitems, tmp, 0, 3782 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0);
3704 m->difficulty,0);
3705 tmp->randomitems = NULL; 3783 tmp->randomitems = NULL;
3706 } 3784 }
3707 else if(tmp->type==TIMED_GATE) { 3785 else if (tmp->type == TIMED_GATE)
3786 {
3708 object *head = tmp->head != NULL ? tmp->head : tmp; 3787 object *head = tmp->head != NULL ? tmp->head : tmp;
3788
3709 if (QUERY_FLAG(head, FLAG_IS_LINKED)) { 3789 if (QUERY_FLAG (head, FLAG_IS_LINKED))
3710 tmp->speed = 0; 3790 {
3711 update_ob_speed(tmp); 3791 tmp->speed = 0;
3712 } 3792 update_ob_speed (tmp);
3713 } 3793 }
3794 }
3714 /* This function can be called everytime a map is loaded, even when 3795 /* This function can be called everytime a map is loaded, even when
3715 * swapping back in. As such, we don't want to create the treasure 3796 * swapping back in. As such, we don't want to create the treasure
3716 * over and ove again, so after we generate the treasure, blank out 3797 * over and ove again, so after we generate the treasure, blank out
3717 * randomitems so if it is swapped in again, it won't make anything. 3798 * randomitems so if it is swapped in again, it won't make anything.
3718 * This is a problem for the above objects, because they have counters 3799 * This is a problem for the above objects, because they have counters
3719 * which say how many times to make the treasure. 3800 * which say how many times to make the treasure.
3720 */ 3801 */
3721 else if(tmp && tmp->arch && tmp->type!=PLAYER && tmp->type!=TREASURE && 3802 else if (tmp && tmp->arch && tmp->type != PLAYER
3722 tmp->type != SPELL && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && 3803 && tmp->type != TREASURE && tmp->type != SPELL
3723 HAS_RANDOM_ITEMS(tmp)) { 3804 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && HAS_RANDOM_ITEMS (tmp))
3805 {
3724 create_treasure(tmp->randomitems, tmp, GT_APPLY, 3806 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0);
3725 m->difficulty,0);
3726 tmp->randomitems = NULL; 3807 tmp->randomitems = NULL;
3727 } 3808 }
3728 } 3809 }
3729 3810
3730 for(x=0;x<MAP_WIDTH(m);x++) 3811 for (x = 0; x < MAP_WIDTH (m); x++)
3731 for(y=0;y<MAP_HEIGHT(m);y++) 3812 for (y = 0; y < MAP_HEIGHT (m); y++)
3732 for(tmp=get_map_ob(m,x,y);tmp!=NULL;tmp=tmp->above) 3813 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above)
3733 if (tmp->above &&
3734 (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL)) 3814 if (tmp->above && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
3735 check_trigger (tmp, tmp->above); 3815 check_trigger (tmp, tmp->above);
3736} 3816}
3737 3817
3738/** 3818/**
3739 * Handles player eating food that temporarily changes status (resistances, stats). 3819 * Handles player eating food that temporarily changes status (resistances, stats).
3740 * This used to call cast_change_attr(), but 3820 * This used to call cast_change_attr(), but
3741 * that doesn't work with the new spell code. Since we know what 3821 * that doesn't work with the new spell code. Since we know what
3742 * the food changes, just grab a force and use that instead. 3822 * the food changes, just grab a force and use that instead.
3743 */ 3823 */
3744 3824
3825void
3745void eat_special_food(object *who, object *food) { 3826eat_special_food (object *who, object *food)
3827{
3746 object *force; 3828 object *force;
3747 int i, did_one=0; 3829 int i, did_one = 0;
3748 sint8 k; 3830 sint8 k;
3749 3831
3750 force = get_archetype(FORCE_NAME); 3832 force = get_archetype (FORCE_NAME);
3751 3833
3752 for (i=0; i < NUM_STATS; i++) { 3834 for (i = 0; i < NUM_STATS; i++)
3835 {
3753 k = get_attr_value(&food->stats, i); 3836 k = get_attr_value (&food->stats, i);
3754 if (k) { 3837 if (k)
3838 {
3755 set_attr_value(&force->stats, i, k); 3839 set_attr_value (&force->stats, i, k);
3756 did_one = 1; 3840 did_one = 1;
3757 } 3841 }
3758 } 3842 }
3759 3843
3760 /* check if we can protect the eater */ 3844 /* check if we can protect the eater */
3761 for (i=0; i<NROFATTACKS; i++) { 3845 for (i = 0; i < NROFATTACKS; i++)
3846 {
3762 if (food->resist[i]>0) { 3847 if (food->resist[i] > 0)
3848 {
3763 force->resist[i] = food->resist[i] / 2; 3849 force->resist[i] = food->resist[i] / 2;
3764 did_one = 1; 3850 did_one = 1;
3765 } 3851 }
3766 } 3852 }
3767 if (did_one) { 3853 if (did_one)
3854 {
3768 force->speed = 0.1; 3855 force->speed = 0.1;
3769 update_ob_speed(force); 3856 update_ob_speed (force);
3770 /* bigger morsel of food = longer effect time */ 3857 /* bigger morsel of food = longer effect time */
3771 force->stats.food = food->stats.food / 5; 3858 force->stats.food = food->stats.food / 5;
3772 SET_FLAG(force, FLAG_IS_USED_UP); 3859 SET_FLAG (force, FLAG_IS_USED_UP);
3773 SET_FLAG(force, FLAG_APPLIED); 3860 SET_FLAG (force, FLAG_APPLIED);
3774 change_abil(who, force); 3861 change_abil (who, force);
3775 insert_ob_in_ob(force, who); 3862 insert_ob_in_ob (force, who);
3776 } else { 3863 }
3864 else
3865 {
3777 free_object(force); 3866 free_object (force);
3778 } 3867 }
3779 3868
3780 /* check for hp, sp change */ 3869 /* check for hp, sp change */
3781 if(food->stats.hp!=0) { 3870 if (food->stats.hp != 0)
3871 {
3782 if(QUERY_FLAG(food, FLAG_CURSED)) { 3872 if (QUERY_FLAG (food, FLAG_CURSED))
3873 {
3783 strcpy(who->contr->killer,food->name); 3874 strcpy (who->contr->killer, food->name);
3784 hit_player(who, food->stats.hp, food, AT_POISON, 1); 3875 hit_player (who, food->stats.hp, food, AT_POISON, 1);
3785 new_draw_info(NDI_UNIQUE, 0,who,"Eck!...that was poisonous!"); 3876 new_draw_info (NDI_UNIQUE, 0, who, "Eck!...that was poisonous!");
3786 } else { 3877 }
3878 else
3879 {
3787 if(food->stats.hp>0) 3880 if (food->stats.hp > 0)
3788 new_draw_info(NDI_UNIQUE, 0,who,"You begin to feel better."); 3881 new_draw_info (NDI_UNIQUE, 0, who, "You begin to feel better.");
3789 else 3882 else
3790 new_draw_info(NDI_UNIQUE, 0,who,"Eck!...that was poisonous!"); 3883 new_draw_info (NDI_UNIQUE, 0, who, "Eck!...that was poisonous!");
3791 who->stats.hp += food->stats.hp; 3884 who->stats.hp += food->stats.hp;
3792 } 3885 }
3793 } 3886 }
3794 if(food->stats.sp!=0) { 3887 if (food->stats.sp != 0)
3888 {
3795 if(QUERY_FLAG(food, FLAG_CURSED)) { 3889 if (QUERY_FLAG (food, FLAG_CURSED))
3890 {
3796 new_draw_info(NDI_UNIQUE, 0,who,"You are drained of mana!"); 3891 new_draw_info (NDI_UNIQUE, 0, who, "You are drained of mana!");
3797 who->stats.sp -= food->stats.sp; 3892 who->stats.sp -= food->stats.sp;
3798 if(who->stats.sp<0) who->stats.sp=0; 3893 if (who->stats.sp < 0)
3799 } else { 3894 who->stats.sp = 0;
3895 }
3896 else
3897 {
3800 new_draw_info(NDI_UNIQUE, 0,who,"You feel a rush of magical energy!"); 3898 new_draw_info (NDI_UNIQUE, 0, who, "You feel a rush of magical energy!");
3801 who->stats.sp += food->stats.sp; 3899 who->stats.sp += food->stats.sp;
3802 /* place limit on max sp from food? */ 3900 /* place limit on max sp from food? */
3901 }
3803 } 3902 }
3804 }
3805 fix_player(who); 3903 fix_player (who);
3806} 3904}
3807 3905
3808 3906
3809/** 3907/**
3810 * Designed primarily to light torches/lanterns/etc. 3908 * Designed primarily to light torches/lanterns/etc.
3811 * Also burns up burnable material too. First object in the inventory is 3909 * Also burns up burnable material too. First object in the inventory is
3812 * the selected object to "burn". -b.t. 3910 * the selected object to "burn". -b.t.
3813 */ 3911 */
3814 3912
3913void
3815void apply_lighter(object *who, object *lighter) { 3914apply_lighter (object *who, object *lighter)
3915{
3816 object *item; 3916 object *item;
3817 int is_player_env=0; 3917 int is_player_env = 0;
3818 uint32 nrof;
3819 tag_t count;
3820 char item_name[MAX_BUF]; 3918 char item_name[MAX_BUF];
3821 3919
3822 item=find_marked_object(who); 3920 item = find_marked_object (who);
3823 if(item) { 3921 if (item)
3922 {
3824 if(lighter->last_eat && lighter->stats.food) { /* lighter gets used up */ 3923 if (lighter->last_eat && lighter->stats.food)
3924 { /* lighter gets used up */
3825 /* Split multiple lighters if they're being used up. Otherwise * 3925 /* Split multiple lighters if they're being used up. Otherwise *
3826 * one charge from each would be used up. --DAMN */ 3926 * one charge from each would be used up. --DAMN */
3827 if(lighter->nrof > 1) { 3927 if (lighter->nrof > 1)
3928 {
3828 object *oneLighter = get_object(); 3929 object *oneLighter = get_object ();
3930
3829 copy_object(lighter, oneLighter); 3931 copy_object (lighter, oneLighter);
3830 lighter->nrof -= 1; 3932 lighter->nrof -= 1;
3831 oneLighter->nrof = 1; 3933 oneLighter->nrof = 1;
3832 oneLighter->stats.food--; 3934 oneLighter->stats.food--;
3833 esrv_send_item(who, lighter); 3935 esrv_send_item (who, lighter);
3834 oneLighter=insert_ob_in_ob(oneLighter, who); 3936 oneLighter = insert_ob_in_ob (oneLighter, who);
3835 esrv_send_item(who, oneLighter); 3937 esrv_send_item (who, oneLighter);
3836 } else { 3938 }
3939 else
3837 lighter->stats.food--; 3940 lighter->stats.food--;
3838 } 3941 }
3839 3942 else if (lighter->last_eat)
3840 } else if(lighter->last_eat) { /* no charges left in lighter */ 3943 { /* no charges left in lighter */
3841 new_draw_info_format(NDI_UNIQUE, 0,who, 3944 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with a used up %s.", &item->name, &lighter->name);
3842 "You attempt to light the %s with a used up %s.",
3843 item->name, lighter->name);
3844 return; 3945 return;
3845 } 3946 }
3846 /* Perhaps we should split what we are trying to light on fire? 3947 /* Perhaps we should split what we are trying to light on fire?
3847 * I can't see many times when you would want to light multiple 3948 * I can't see many times when you would want to light multiple
3848 * objects at once. 3949 * objects at once.
3849 */ 3950 */
3850 nrof=item->nrof;
3851 count=item->count;
3852 /* If the item is destroyed, we don't have a valid pointer to the 3951 /* If the item is destroyed, we don't have a valid pointer to the
3853 * name object, so make a copy so the message we print out makes 3952 * name object, so make a copy so the message we print out makes
3854 * some sense. 3953 * some sense.
3855 */ 3954 */
3856 strcpy(item_name, item->name); 3955 strcpy (item_name, item->name);
3857 if (who == is_player_inv(item)) is_player_env=1; 3956 if (who == is_player_inv (item))
3957 is_player_env = 1;
3858 3958
3859 save_throw_object(item,AT_FIRE,who); 3959 save_throw_object (item, AT_FIRE, who);
3860 /* Change to check count and not freed, since the object pointer 3960 /* Change to check count and not freed, since the object pointer
3861 * may have gotten recycled 3961 * may have gotten recycled
3862 */ 3962 */
3863 if ((nrof != item->nrof ) || (count != item->count)) { 3963 if (item->destroyed ())
3864 new_draw_info_format(NDI_UNIQUE, 0,who, 3964 {
3865 "You light the %s with the %s.",item_name,lighter->name); 3965 new_draw_info_format (NDI_UNIQUE, 0, who, "You light the %s with the %s.", &item_name, &lighter->name);
3866 /* Need to update the player so that the players glow radius 3966 /* Need to update the player so that the players glow radius
3867 * gets changed. 3967 * gets changed.
3868 */ 3968 */
3869 if (is_player_env) fix_player(who); 3969 if (is_player_env)
3870 } else { 3970 fix_player (who);
3871 new_draw_info_format(NDI_UNIQUE, 0,who, 3971 }
3872 "You attempt to light the %s with the %s and fail.",item->name,lighter->name); 3972 else
3873 } 3973 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with the %s and fail.", &item->name, &lighter->name);
3874 3974 }
3875 } else /* nothing to light */ 3975 else /* nothing to light */
3876 new_draw_info(NDI_UNIQUE, 0,who,"You need to mark a lightable object."); 3976 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object.");
3877 3977
3878} 3978}
3879 3979
3880/** 3980/**
3881 * op made some mistake with a scroll, this takes care of punishment. 3981 * op made some mistake with a scroll, this takes care of punishment.
3882 * scroll_failure()- hacked directly from spell_failure 3982 * scroll_failure()- hacked directly from spell_failure
3883 */ 3983 */
3984void
3884void scroll_failure(object *op, int failure, int power) 3985scroll_failure (object *op, int failure, int power)
3885{ 3986{
3886 if(abs(failure/4)>power) power=abs(failure/4); /* set minimum effect */ 3987 if (abs (failure / 4) > power)
3988 power = abs (failure / 4); /* set minimum effect */
3887 3989
3888 if(failure<= -1&&failure > -15) {/* wonder */ 3990 if (failure <= -1 && failure > -15)
3991 { /* wonder */
3889 object *tmp; 3992 object *tmp;
3890 3993
3891 new_draw_info(NDI_UNIQUE, 0,op,"Your spell warps!."); 3994 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!.");
3892 tmp=get_archetype(SPELL_WONDER); 3995 tmp = get_archetype (SPELL_WONDER);
3893 cast_wonder(op, op, 0, tmp); 3996 cast_wonder (op, op, 0, tmp);
3894 free_object(tmp); 3997 free_object (tmp);
3998 }
3895 } else if (failure <= -15&&failure > -35) {/* drain mana */ 3999 else if (failure <= -15 && failure > -35)
4000 { /* drain mana */
3896 new_draw_info(NDI_UNIQUE, 0,op,"Your mana is drained!."); 4001 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!.");
3897 op->stats.sp -= random_roll(0, power-1, op, PREFER_LOW); 4002 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW);
3898 if(op->stats.sp<0) op->stats.sp = 0; 4003 if (op->stats.sp < 0)
4004 op->stats.sp = 0;
4005 }
3899 } else if (settings.spell_failure_effects == TRUE) { 4006 else if (settings.spell_failure_effects == TRUE)
3900 if (failure <= -35&&failure > -60) { /* confusion */ 4007 {
4008 if (failure <= -35 && failure > -60)
4009 { /* confusion */
3901 new_draw_info(NDI_UNIQUE, 0,op,"The magic recoils on you!"); 4010 new_draw_info (NDI_UNIQUE, 0, op, "The magic recoils on you!");
3902 confuse_player(op,op,power); 4011 confuse_player (op, op, power);
3903 } else if (failure <= -60&&failure> -70) {/* paralysis */ 4012 }
4013 else if (failure <= -60 && failure > -70)
4014 { /* paralysis */
3904 new_draw_info(NDI_UNIQUE, 0,op,"The magic recoils and paralyzes " 4015 new_draw_info (NDI_UNIQUE, 0, op, "The magic recoils and paralyzes " "you!");
3905 "you!");
3906 paralyze_player(op,op,power); 4016 paralyze_player (op, op, power);
4017 }
3907 } else if (failure <= -70&&failure> -80) {/* blind */ 4018 else if (failure <= -70 && failure > -80)
4019 { /* blind */
3908 new_draw_info(NDI_UNIQUE, 0,op,"The magic recoils on you!"); 4020 new_draw_info (NDI_UNIQUE, 0, op, "The magic recoils on you!");
3909 blind_player(op,op,power); 4021 blind_player (op, op, power);
3910 } else if (failure <= -80) {/* blast the immediate area */ 4022 }
4023 else if (failure <= -80)
4024 { /* blast the immediate area */
3911 object *tmp; 4025 object *tmp;
4026
3912 tmp=get_archetype(LOOSE_MANA); 4027 tmp = get_archetype (LOOSE_MANA);
3913 cast_magic_storm(op,tmp, power); 4028 cast_magic_storm (op, tmp, power);
3914 new_draw_info(NDI_UNIQUE, 0,op,"You unlease uncontrolled mana!"); 4029 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!");
3915 free_object(tmp); 4030 free_object (tmp);
3916 } 4031 }
3917 } 4032 }
3918} 4033}
3919 4034
4035void
3920void apply_changes_to_player(object *pl, object *change) { 4036apply_changes_to_player (object *pl, object *change)
4037{
3921 int excess_stat=0; /* if the stat goes over the maximum 4038 int excess_stat = 0; /* if the stat goes over the maximum
3922 for the race, put the excess stat some 4039 for the race, put the excess stat some
3923 where else. */ 4040 where else. */
3924 4041
3925 switch (change->type) { 4042 switch (change->type)
3926 case CLASS: { 4043 {
4044 case CLASS:
4045 {
3927 living *stats = &(pl->contr->orig_stats); 4046 living *stats = &(pl->contr->orig_stats);
3928 living *ns = &(change->stats); 4047 living *ns = &(change->stats);
3929 object *walk; 4048 object *walk;
3930 int flag_change_face=1; 4049 int flag_change_face = 1;
3931 4050
3932 /* the following code assigns stats up to the stat max 4051 /* the following code assigns stats up to the stat max
3933 * for the race, and if the stat max is exceeded, 4052 * for the race, and if the stat max is exceeded,
3934 * tries to randomly reassign the excess stat 4053 * tries to randomly reassign the excess stat
3935 */ 4054 */
3936 int i,j; 4055 int i, j;
4056
3937 for(i=0;i<NUM_STATS;i++) { 4057 for (i = 0; i < NUM_STATS; i++)
4058 {
3938 sint8 stat=get_attr_value(stats,i); 4059 sint8 stat = get_attr_value (stats, i);
3939 int race_bonus = get_attr_value(&(pl->arch->clone.stats),i); 4060 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4061
3940 stat += get_attr_value(ns,i); 4062 stat += get_attr_value (ns, i);
3941 if(stat > 20 + race_bonus) { 4063 if (stat > 20 + race_bonus)
3942 excess_stat++; 4064 {
3943 stat = 20+race_bonus; 4065 excess_stat++;
3944 } 4066 stat = 20 + race_bonus;
4067 }
3945 set_attr_value(stats,i,stat); 4068 set_attr_value (stats, i, stat);
3946 } 4069 }
3947 4070
3948 for(j=0;excess_stat >0 && j<100;j++) {/* try 100 times to assign excess stats */ 4071 for (j = 0; excess_stat > 0 && j < 100; j++)
3949 int i = rndm(0, 6); 4072 { /* try 100 times to assign excess stats */
4073 int i = rndm (0, 6);
3950 int stat=get_attr_value(stats,i); 4074 int stat = get_attr_value (stats, i);
3951 int race_bonus = get_attr_value(&(pl->arch->clone.stats),i); 4075 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
3952 if(i==CHA) continue; /* exclude cha from this */ 4076
3953 if( stat < 20 + race_bonus) { 4077 if (i == CHA)
4078 continue; /* exclude cha from this */
4079 if (stat < 20 + race_bonus)
4080 {
3954 change_attr_value(stats,i,1); 4081 change_attr_value (stats, i, 1);
3955 excess_stat--; 4082 excess_stat--;
3956 } 4083 }
3957 } 4084 }
3958 4085
3959 /* insert the randomitems from the change's treasurelist into 4086 /* insert the randomitems from the change's treasurelist into
3960 * the player ref: player.c 4087 * the player ref: player.c
3961 */ 4088 */
3962 if(change->randomitems!=NULL) 4089 if (change->randomitems != NULL)
3963 give_initial_items(pl,change->randomitems); 4090 give_initial_items (pl, change->randomitems);
3964 4091
3965 4092
3966 /* set up the face, for some races. */ 4093 /* set up the face, for some races. */
3967 4094
3968 /* first, look for the force object banning 4095 /* first, look for the force object banning
3969 * changing the face. Certain races never change face with class. 4096 * changing the face. Certain races never change face with class.
3970 */ 4097 */
3971 for(walk=pl->inv;walk!=NULL;walk=walk->below) 4098 for (walk = pl->inv; walk != NULL; walk = walk->below)
3972 if (!strcmp(walk->name,"NOCLASSFACECHANGE")) flag_change_face=0; 4099 if (!strcmp (walk->name, "NOCLASSFACECHANGE"))
4100 flag_change_face = 0;
3973 4101
3974 if(flag_change_face) { 4102 if (flag_change_face)
4103 {
3975 pl->animation_id = GET_ANIM_ID(change); 4104 pl->animation_id = GET_ANIM_ID (change);
3976 pl->face = change->face; 4105 pl->face = change->face;
3977 4106
3978 if(QUERY_FLAG(change,FLAG_ANIMATE)) 4107 if (QUERY_FLAG (change, FLAG_ANIMATE))
3979 SET_FLAG(pl,FLAG_ANIMATE); 4108 SET_FLAG (pl, FLAG_ANIMATE);
3980 else 4109 else
3981 CLEAR_FLAG(pl,FLAG_ANIMATE); 4110 CLEAR_FLAG (pl, FLAG_ANIMATE);
3982 } 4111 }
3983 4112
3984 /* check the special case of can't use weapons */ 4113 /* check the special case of can't use weapons */
3985 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON);*/ 4114 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */
3986 if(!strcmp(change->name,"monk")) CLEAR_FLAG(pl,FLAG_USE_WEAPON); 4115 if (!strcmp (change->name, "monk"))
4116 CLEAR_FLAG (pl, FLAG_USE_WEAPON);
3987 4117
3988 break; 4118 break;
3989 } 4119 }
3990 } 4120 }
3991} 4121}
3992 4122
3993/** 4123/**
3994 * This handles items of type 'transformer'. 4124 * This handles items of type 'transformer'.
3998 * Change information is contained in the 'slaying' field of the marked item. 4128 * Change information is contained in the 'slaying' field of the marked item.
3999 * The format is as follow: transformer:[number ]yield[;transformer:...]. 4129 * The format is as follow: transformer:[number ]yield[;transformer:...].
4000 * This way an item can be transformed in many things, and/or many objects. 4130 * This way an item can be transformed in many things, and/or many objects.
4001 * The 'slaying' field for transformer is used as verb for the action. 4131 * The 'slaying' field for transformer is used as verb for the action.
4002 */ 4132 */
4133void
4003void apply_item_transformer( object* pl, object* transformer ) 4134apply_item_transformer (object *pl, object *transformer)
4004 { 4135{
4005 object* marked; 4136 object *marked;
4006 object* new_item; 4137 object *new_item;
4007 char* find; 4138 char *find;
4008 char* separator; 4139 char *separator;
4009 int yield; 4140 int yield;
4010 char got[ MAX_BUF ]; 4141 char got[MAX_BUF];
4011 int len; 4142 int len;
4012 4143
4013 if ( !pl || !transformer ) 4144 if (!pl || !transformer)
4014 return; 4145 return;
4015 marked = find_marked_object( pl ); 4146 marked = find_marked_object (pl);
4016 if ( !marked ) 4147 if (!marked)
4017 { 4148 {
4018 new_draw_info_format( NDI_UNIQUE, 0, pl, "Use the %s with what item?", query_name( transformer ) ); 4149 new_draw_info_format (NDI_UNIQUE, 0, pl, "Use the %s with what item?", query_name (transformer));
4019 return; 4150 return;
4020 } 4151 }
4021 if ( !marked->slaying ) 4152 if (!marked->slaying)
4022 { 4153 {
4023 new_draw_info_format( NDI_UNIQUE, 0, pl, "You can't use the %s with your %s!", query_name( transformer ), query_name( marked ) ); 4154 new_draw_info_format (NDI_UNIQUE, 0, pl, "You can't use the %s with your %s!", query_name (transformer), query_name (marked));
4024 return; 4155 return;
4025 } 4156 }
4026 /* check whether they are compatible or not */ 4157 /* check whether they are compatible or not */
4027 find = strstr( marked->slaying, transformer->arch->name ); 4158 find = strstr (marked->slaying, transformer->arch->name);
4028 if ( !find || ( *( find + strlen( transformer->arch->name ) ) != ':' ) ) 4159 if (!find || (*(find + strlen (transformer->arch->name)) != ':'))
4029 { 4160 {
4030 new_draw_info_format( NDI_UNIQUE, 0, pl, "You can't use the %s with your %s!", query_name( transformer ), query_name( marked ) ); 4161 new_draw_info_format (NDI_UNIQUE, 0, pl, "You can't use the %s with your %s!", query_name (transformer), query_name (marked));
4031 return; 4162 return;
4032 } 4163 }
4033 find += strlen( transformer->arch->name ) + 1; 4164 find += strlen (transformer->arch->name) + 1;
4034 /* Item can be used, now find how many and what it yields */ 4165 /* Item can be used, now find how many and what it yields */
4035 if ( isdigit( *( find ) ) ) 4166 if (isdigit (*(find)))
4036 { 4167 {
4037 yield = atoi( find ); 4168 yield = atoi (find);
4038 if ( yield < 1 ) 4169 if (yield < 1)
4039 { 4170 {
4040 LOG( llevDebug, "apply_item_transformer: item %s has slaying-yield %d.", query_base_name( marked, 0 ), yield ); 4171 LOG (llevDebug, "apply_item_transformer: item %s has slaying-yield %d.", query_base_name (marked, 0), yield);
4041 yield = 1; 4172 yield = 1;
4042 } 4173 }
4043 } 4174 }
4044 else 4175 else
4045 yield = 1; 4176 yield = 1;
4046 4177
4047 while ( isdigit( *find ) ) 4178 while (isdigit (*find))
4048 find++; 4179 find++;
4049 while ( *find == ' ' ) 4180 while (*find == ' ')
4050 find++; 4181 find++;
4051 memset( got, 0, MAX_BUF ); 4182 memset (got, 0, MAX_BUF);
4052 if ( (separator = strchr( find, ';' ))!=NULL) 4183 if ((separator = strchr (find, ';')) != NULL)
4053 { 4184 {
4054 len = separator - find; 4185 len = separator - find;
4055 } 4186 }
4056 else 4187 else
4057 { 4188 {
4058 len = strlen(find); 4189 len = strlen (find);
4059 } 4190 }
4060 if ( len > MAX_BUF-1) 4191 if (len > MAX_BUF - 1)
4061 len = MAX_BUF-1; 4192 len = MAX_BUF - 1;
4062 strcpy( got, find ); 4193 strcpy (got, find);
4063 got[len] = '\0'; 4194 got[len] = '\0';
4064 4195
4065 /* Now create new item, remove used ones when required. */ 4196 /* Now create new item, remove used ones when required. */
4066 new_item = get_archetype( got ); 4197 new_item = get_archetype (got);
4067 if ( !new_item ) 4198 if (!new_item)
4068 { 4199 {
4069 new_draw_info_format( NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name( marked, 0 ) ); 4200 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0));
4070 return; 4201 return;
4071 } 4202 }
4203
4072 new_item->nrof = yield; 4204 new_item->nrof = yield;
4073 new_draw_info_format( NDI_UNIQUE, 0, pl, "You %s the %s.", transformer->slaying, query_base_name( marked, 0 ) ); 4205 new_draw_info_format (NDI_UNIQUE, 0, pl, "You %s the %s.", &transformer->slaying, query_base_name (marked, 0));
4074 insert_ob_in_ob( new_item, pl ); 4206 insert_ob_in_ob (new_item, pl);
4075 esrv_send_inventory( pl, pl ); 4207 esrv_send_inventory (pl, pl);
4076 /* Eat up one item */ 4208 /* Eat up one item */
4077 decrease_ob_nr( marked, 1 ); 4209 decrease_ob_nr (marked, 1);
4078 /* Eat one transformer if needed */ 4210 /* Eat one transformer if needed */
4079 if ( transformer->stats.food ) 4211 if (transformer->stats.food)
4080 if ( --transformer->stats.food == 0 ) 4212 if (--transformer->stats.food == 0)
4081 decrease_ob_nr( transformer, 1 ); 4213 decrease_ob_nr (transformer, 1);
4082 } 4214}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines