ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.125
Committed: Sun Apr 11 04:41:44 2010 UTC (14 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.124: +27 -26 lines
Log Message:
mroe failmsg

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.77 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 pippijn 1.35 *
4 root 1.120 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 root 1.119 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6     * Copyright (©) 1992 Frank Tore Johansen
7 pippijn 1.35 *
8 root 1.110 * Deliantra is free software: you can redistribute it and/or modify it under
9     * the terms of the Affero GNU General Public License as published by the
10     * Free Software Foundation, either version 3 of the License, or (at your
11     * option) any later version.
12 pippijn 1.35 *
13 root 1.62 * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17 pippijn 1.35 *
18 root 1.110 * You should have received a copy of the Affero GNU General Public License
19     * and the GNU General Public License along with this program. If not, see
20     * <http://www.gnu.org/licenses/>.
21 root 1.54 *
22 root 1.77 * The authors can be reached via e-mail to <support@deliantra.net>
23 pippijn 1.35 */
24 elmex 1.1
25     #include <global.h>
26     #include <object.h>
27     #include <living.h>
28 root 1.36 #include <sproto.h>
29 elmex 1.1 #include <spells.h>
30     #include <sounds.h>
31    
32     /* cast_magic_storm: This is really used mostly for spell
33     * fumbles at the like. tmp is the object to propogate.
34     * op is what is casting this.
35     */
36 root 1.8 void
37     cast_magic_storm (object *op, object *tmp, int lvl)
38 elmex 1.1 {
39 root 1.8 if (!tmp)
40     return; /* error */
41 root 1.27
42 root 1.8 tmp->level = op->level;
43     tmp->range += lvl / 5; /* increase the area of destruction */
44     tmp->duration += lvl / 5;
45    
46     /* Put a cap on duration for this - if the player fails in their
47     * apartment, don't want it to go on so long that it kills them
48     * multiple times. Also, damge already increases with level,
49     * so don't really need to increase the duration as much either.
50     */
51     if (tmp->duration >= 40)
52     tmp->duration = 40;
53 root 1.27
54 root 1.8 tmp->stats.dam = lvl; /* nasty recoils! */
55     tmp->stats.maxhp = tmp->count; /* tract single parent */
56 elmex 1.1
57 root 1.27 tmp->insert_at (op, op);
58 elmex 1.1 }
59    
60 root 1.8 int
61     recharge (object *op, object *caster, object *spell_ob)
62     {
63     object *wand, *tmp;
64     int ncharges;
65    
66     wand = find_marked_object (op);
67 root 1.84 if (!wand || wand->type != WAND)
68 root 1.8 {
69 root 1.125 op->failmsg ("You need to mark the wand you want to recharge.");
70 root 1.8 return 0;
71 elmex 1.1 }
72 root 1.125
73 root 1.8 if (!(random_roll (0, 3, op, PREFER_HIGH)))
74     {
75 root 1.125 op->failmsgf ("The %s vibrates violently, then explodes!", query_name (wand));
76 root 1.64 op->play_sound (sound_find ("ob_explode"));
77 root 1.91 wand->destroy ();
78 root 1.113 tmp = get_archetype (shstr_fireball);
79 root 1.8 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob)) / 10;
80 root 1.27
81 root 1.8 if (!tmp->stats.dam)
82     tmp->stats.dam = 1;
83 root 1.27
84 root 1.8 tmp->stats.hp = tmp->stats.dam / 2;
85 root 1.27
86 root 1.8 if (tmp->stats.hp < 2)
87     tmp->stats.hp = 2;
88 root 1.27
89     tmp->insert_at (op);
90 root 1.8 return 1;
91     }
92    
93     ncharges = (spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob));
94 root 1.27
95 root 1.8 if (wand->inv && wand->inv->level)
96     ncharges /= wand->inv->level;
97     else
98     {
99 root 1.125 op->failmsgf ("Your %s is broken.", query_name (wand));
100 root 1.8 return 0;
101 elmex 1.1 }
102 root 1.27
103 root 1.8 if (!ncharges)
104     ncharges = 1;
105 elmex 1.1
106 root 1.8 wand->stats.food += ncharges;
107     new_draw_info_format (NDI_UNIQUE, 0, op, "The %s glows with power.", query_name (wand));
108 root 1.27
109 root 1.124 if (wand->arch && wand->arch->flag [FLAG_ANIMATE])
110 root 1.8 {
111 root 1.124 wand->set_flag (FLAG_ANIMATE);
112 root 1.57 wand->set_speed (wand->arch->speed);
113 elmex 1.1 }
114 root 1.26
115 root 1.8 return 1;
116 elmex 1.1 }
117    
118     /* Create a missile (nonmagic - magic +4). Will either create bolts or arrows
119     * based on whether a crossbow or bow is equiped. If neither, it defaults to
120     * arrows.
121     * Sets the plus based on the casters level. It is also settable with the
122     * invoke command. If the caster attempts to create missiles with too
123     * great a plus, the default is used.
124     * The # of arrows created also goes up with level, so if a 30th level mage
125     * wants LOTS of arrows, and doesn't care what the plus is he could
126     * create nonnmagic arrows, or even -1, etc...
127     */
128 root 1.8 int
129 root 1.104 cast_create_missile (object *op, object *caster, object *spell, int dir, const char *spellparam)
130 elmex 1.1 {
131 root 1.74 int bonus_plus = 0;
132     const char *missile_name = "arrow";
133 root 1.8
134 root 1.74 for (object *tmp = op->inv; tmp; tmp = tmp->below)
135 root 1.124 if (tmp->type == BOW && tmp->flag [FLAG_APPLIED])
136 root 1.12 missile_name = tmp->race;
137 elmex 1.1
138 root 1.74 int missile_plus = spell->stats.dam + SP_level_dam_adjust (caster, spell);
139    
140     archetype *missile_arch = archetype::find (missile_name);
141 elmex 1.1
142 root 1.74 if (!missile_arch)
143 root 1.8 {
144     LOG (llevDebug, "Cast create_missile: could not find archetype %s\n", missile_name);
145     return 0;
146     }
147 root 1.12
148 root 1.74 object *missile = missile_arch->instance ();
149 elmex 1.1
150 root 1.104 if (spellparam)
151 root 1.8 {
152     /* If it starts with a letter, presume it is a description */
153 root 1.104 if (isalpha (*spellparam))
154 root 1.8 {
155     artifact *al = find_artifactlist (missile->type)->items;
156 elmex 1.1
157 root 1.45 for (; al; al = al->next)
158 root 1.104 if (!strcasecmp (al->item->name, spellparam))
159 root 1.8 break;
160    
161     if (!al)
162     {
163 root 1.91 missile->destroy ();
164 root 1.125 op->failmsgf ("No such object %ss of %s", missile_name, spellparam);
165 root 1.8 return 0;
166     }
167 root 1.12
168 root 1.8 if (al->item->slaying)
169     {
170 root 1.91 missile->destroy ();
171 root 1.125 op->failmsgf ("You are not allowed to create %ss of %s", missile_name, spellparam);
172 root 1.8 return 0;
173     }
174 root 1.12
175 root 1.8 give_artifact_abilities (missile, al->item);
176 root 1.74 /* These special arrows cost something extra. Don't have them also be magical -
177     * otherwise, in most cases, not enough will be created. I don't want to get into
178 root 1.8 * the parsing of having to do both plus and type.
179     */
180     bonus_plus = 1 + (al->item->value / 5);
181     missile_plus = 0;
182     }
183 root 1.104 else if (atoi (spellparam) < missile_plus)
184     missile_plus = atoi (spellparam);
185 root 1.8 }
186 root 1.12
187 root 1.74 missile_plus = clamp (missile_plus, -4, 4);
188 root 1.8
189     missile->nrof = spell->duration + SP_level_duration_adjust (caster, spell);
190     missile->nrof -= 3 * (missile_plus + bonus_plus);
191 root 1.12
192 root 1.8 if (missile->nrof < 1)
193     missile->nrof = 1;
194    
195     missile->magic = missile_plus;
196     /* Can't get any money for these objects */
197     missile->value = 0;
198 elmex 1.1
199 root 1.124 missile->set_flag (FLAG_IDENTIFIED);
200 elmex 1.1
201 root 1.12 if (!cast_create_obj (op, caster, missile, dir) && op->type == PLAYER && !missile->destroyed ())
202     pick_up (op, missile);
203    
204 root 1.8 return 1;
205 elmex 1.1 }
206    
207    
208     /* allows the choice of what sort of food object to make.
209 root 1.104 * If spellparam is NULL, it will create food dependent on level --PeterM*/
210 root 1.8 int
211 root 1.104 cast_create_food (object *op, object *caster, object *spell_ob, int dir, const char *spellparam)
212 elmex 1.1 {
213 root 1.8 int food_value;
214     archetype *at = NULL;
215     object *new_op;
216    
217 root 1.76 food_value = spell_ob->stats.food + 50 * SP_level_duration_adjust (caster, spell_ob);
218 root 1.8
219 root 1.104 if (spellparam)
220 root 1.8 {
221 root 1.104 at = find_archetype_by_object_type_name (FOOD, spellparam);
222 root 1.8 if (at == NULL)
223 root 1.104 at = find_archetype_by_object_type_name (DRINK, spellparam);
224 root 1.57 if (at == NULL || at->stats.food > food_value)
225 root 1.104 spellparam = NULL;
226 root 1.8 }
227    
228 root 1.104 if (!spellparam)
229 root 1.8 {
230     archetype *at_tmp;
231    
232     /* We try to find the archetype with the maximum food value.
233     * This removes the dependancy of hard coded food values in this
234     * function, and addition of new food types is automatically added.
235     * We don't use flesh types because the weight values of those need
236     * to be altered from the donor.
237     */
238 root 1.5
239 root 1.8 /* We assume the food items don't have multiple parts */
240 elmex 1.58 for_all_archetypes (at_tmp)
241 root 1.8 {
242 root 1.57 if (at_tmp->type == FOOD || at_tmp->type == DRINK)
243 root 1.8 {
244     /* Basically, if the food value is something that is creatable
245     * under the limits of the spell and it is higher than
246     * the item we have now, take it instead.
247     */
248 elmex 1.59 if (at_tmp->stats.food <= food_value
249     && (!at
250     || at_tmp->stats.food > at->stats.food
251     || (at_tmp->stats.food == at->stats.food
252     && at_tmp->weight < at->weight)))
253 root 1.8 at = at_tmp;
254 root 1.5 }
255     }
256 elmex 1.1 }
257 root 1.65
258 root 1.8 /* Pretty unlikely (there are some very low food items), but you never
259     * know
260     */
261     if (!at)
262     {
263 root 1.125 op->failmsgf ("You don't have enough experience to create any food.");
264 root 1.8 return 0;
265 elmex 1.1 }
266    
267 root 1.57 food_value /= at->stats.food;
268 root 1.116 new_op = at->instance ();
269 root 1.8 new_op->nrof = food_value;
270 elmex 1.1
271 root 1.8 new_op->value = 0;
272     if (new_op->nrof < 1)
273     new_op->nrof = 1;
274 elmex 1.1
275 root 1.8 cast_create_obj (op, caster, new_op, dir);
276     return 1;
277 elmex 1.1 }
278 root 1.8
279     int
280     probe (object *op, object *caster, object *spell_ob, int dir)
281     {
282     int r, mflags, maxrange;
283     object *tmp;
284 root 1.13 maptile *m;
285 elmex 1.1
286 root 1.8 if (!dir)
287     {
288     examine_monster (op, op);
289     return 1;
290 elmex 1.1 }
291 root 1.65
292 root 1.8 maxrange = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
293     for (r = 1; r < maxrange; r++)
294     {
295     sint16 x = op->x + r * freearr_x[dir], y = op->y + r * freearr_y[dir];
296 elmex 1.1
297 root 1.8 m = op->map;
298     mflags = get_map_flags (m, &m, x, y, &x, &y);
299 elmex 1.1
300 root 1.8 if (mflags & P_OUT_OF_MAP)
301     break;
302 elmex 1.1
303 root 1.124 if (!op->flag [FLAG_WIZCAST] && (mflags & P_NO_MAGIC))
304 root 1.8 {
305     new_draw_info (NDI_UNIQUE, 0, op, "Something blocks your magic.");
306     return 0;
307 root 1.5 }
308 root 1.84
309 root 1.8 if (mflags & P_IS_ALIVE)
310     {
311 root 1.84 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above)
312 root 1.124 if (tmp->flag [FLAG_ALIVE] && (tmp->type == PLAYER || tmp->flag [FLAG_MONSTER]))
313 root 1.8 {
314     new_draw_info (NDI_UNIQUE, 0, op, "You detect something.");
315     if (tmp->head != NULL)
316     tmp = tmp->head;
317     examine_monster (op, tmp);
318     return 1;
319     }
320 root 1.5 }
321 elmex 1.1 }
322 root 1.65
323 root 1.8 new_draw_info (NDI_UNIQUE, 0, op, "You detect nothing.");
324     return 1;
325 elmex 1.1 }
326    
327     /* This checks to see if 'pl' is invisible to 'mon'.
328     * does race check, undead check, etc
329     * Returns TRUE if mon can't see pl, false
330     * otherwise. This doesn't check range, walls, etc. It
331     * only checks the racial adjustments, and in fact that
332     * pl is invisible.
333     */
334 root 1.8 int
335     makes_invisible_to (object *pl, object *mon)
336 elmex 1.1 {
337 root 1.8 if (!pl->invisible)
338     return 0;
339 root 1.68
340 root 1.8 if (pl->type == PLAYER)
341     {
342     /* If race isn't set, then invisible unless it is undead */
343     if (!pl->contr->invis_race)
344     {
345 root 1.124 if (mon->flag [FLAG_UNDEAD])
346 root 1.8 return 0;
347 root 1.68
348 root 1.8 return 1;
349     }
350 root 1.68
351 root 1.8 /* invis_race is set if we get here */
352 root 1.95 if (pl->contr->invis_race == shstr_undead && is_true_undead (mon))
353 root 1.8 return 1;
354 root 1.68
355 root 1.8 /* No race, can't be invisible to it */
356     if (!mon->race)
357 root 1.5 return 0;
358 root 1.68
359 root 1.94 if (mon->race.contains (pl->contr->invis_race))
360 root 1.5 return 1;
361 root 1.68
362 root 1.8 /* Nothing matched above, return 0 */
363     return 0;
364     }
365     else
366     {
367     /* monsters are invisible to everything */
368     return 1;
369 elmex 1.1 }
370     }
371    
372     /* Makes the player or character invisible.
373     * Note the spells to 'stack', but perhaps in odd ways.
374     * the duration for all is cumulative.
375     * In terms of invis undead/normal invis, it is the last one cast that
376     * will determine if you are invisible to undead or normal monsters.
377     * For improved invis, if you cast it with a one of the others, you
378     * lose the improved part of it, and the above statement about undead/
379     * normal applies.
380     */
381 root 1.8 int
382     cast_invisible (object *op, object *caster, object *spell_ob)
383     {
384     if (op->invisible > 1000)
385     {
386 root 1.125 op->failmsg ("You can not extend the duration of your invisibility any further");
387 root 1.8 return 0;
388 elmex 1.1 }
389    
390 root 1.8 /* Remove the switch with 90% duplicate code - just handle the differences with
391     * and if statement or two.
392     */
393     op->invisible += spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
394     /* max duration */
395     if (op->invisible > 1000)
396     op->invisible = 1000;
397    
398     if (op->type == PLAYER)
399     {
400     op->contr->invis_race = spell_ob->race;
401    
402 root 1.124 if (spell_ob->flag [FLAG_MAKE_INVIS])
403 root 1.8 op->contr->tmp_invis = 0;
404     else
405     op->contr->tmp_invis = 1;
406    
407     op->contr->hidden = 0;
408     }
409 root 1.42
410 root 1.8 if (makes_invisible_to (op, op))
411     new_draw_info (NDI_UNIQUE, 0, op, "You can't see your hands!");
412     else
413     new_draw_info (NDI_UNIQUE, 0, op, "You feel more transparent!");
414    
415 root 1.42 update_object (op, UP_OBJ_CHANGE);
416 root 1.8
417     /* Only search the active objects - only these should actually do
418     * harm to the player.
419     */
420 root 1.33 for_all_actives (tmp)
421 root 1.8 if (tmp->enemy == op)
422 root 1.33 tmp->enemy = 0;
423    
424 root 1.8 return 1;
425 elmex 1.1 }
426    
427     /* earth to dust spell. Basically destroys earthwalls in the area.
428     */
429 root 1.8 int
430     cast_earth_to_dust (object *op, object *caster, object *spell_ob)
431     {
432     int range, i, j, mflags;
433     sint16 sx, sy;
434 root 1.13 maptile *m;
435 elmex 1.1
436 root 1.8 range = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
437 elmex 1.1
438 root 1.8 for (i = -range; i <= range; i++)
439     for (j = -range; j <= range; j++)
440     {
441     sx = op->x + i;
442     sy = op->y + j;
443     m = op->map;
444     mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
445 elmex 1.1
446 root 1.8 if (mflags & P_OUT_OF_MAP)
447     continue;
448 elmex 1.1
449 root 1.102 // earth to dust tears down everything that can be torn down
450     for (object *next, *tmp = m->at (sx, sy).bot; tmp; tmp = next)
451 root 1.8 {
452     next = tmp->above;
453 root 1.102
454 root 1.124 if (tmp->flag [FLAG_TEAR_DOWN])
455 root 1.8 hit_player (tmp, 9998, op, AT_PHYSICAL, 0);
456     }
457     }
458 root 1.31
459 root 1.8 return 1;
460 elmex 1.1 }
461    
462 root 1.8 void
463     execute_word_of_recall (object *op)
464     {
465 root 1.31 if (object *pl = op->in_player ())
466     {
467 root 1.124 if (pl->ms ().flags () & P_NO_CLERIC && !pl->flag [FLAG_WIZCAST])
468 root 1.31 new_draw_info (NDI_UNIQUE, 0, pl, "You feel something fizzle inside you.");
469     else
470 root 1.82 pl->player_goto (op->slaying, op->stats.hp, op->stats.sp);
471 root 1.31 }
472 root 1.14
473 root 1.91 op->destroy ();
474 elmex 1.1 }
475    
476     /* Word of recall causes the player to return 'home'.
477     * we put a force into the player object, so that there is a
478     * time delay effect.
479     */
480 root 1.8 int
481     cast_word_of_recall (object *op, object *caster, object *spell_ob)
482     {
483     object *dummy;
484     int time;
485 elmex 1.1
486 root 1.8 if (op->type != PLAYER)
487     return 0;
488 elmex 1.1
489 root 1.8 if (find_obj_by_type_subtype (op, SPELL_EFFECT, SP_WORD_OF_RECALL))
490 elmex 1.1 {
491 root 1.8 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
492     return 1;
493 elmex 1.1 }
494    
495 root 1.8 dummy = get_archetype (FORCE_NAME);
496 root 1.84
497     if (!dummy)
498 root 1.8 {
499     new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
500     LOG (llevError, "cast_word_of_recall: get_archetype(force) failed!\n");
501     return 0;
502     }
503 root 1.29
504 root 1.8 time = spell_ob->duration - SP_level_duration_adjust (caster, spell_ob);
505     if (time < 1)
506     time = 1;
507    
508     /* value of speed really doesn't make much difference, as long as it is
509     * positive. Lower value may be useful so that the problem doesn't
510     * do anything really odd if it say a -1000 or something.
511     */
512 root 1.26 dummy->set_speed (0.002);
513 root 1.8 dummy->speed_left = -dummy->speed * time;
514     dummy->type = SPELL_EFFECT;
515     dummy->subtype = SP_WORD_OF_RECALL;
516    
517     /* If we could take advantage of enter_player_savebed() here, it would be
518     * nice, but until the map load fails, we can't.
519     */
520     EXIT_PATH (dummy) = op->contr->savebed_map;
521 root 1.29 EXIT_X (dummy) = op->contr->bed_x;
522     EXIT_Y (dummy) = op->contr->bed_y;
523 root 1.8
524 root 1.31 op->insert (dummy);
525    
526 root 1.8 new_draw_info (NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you.");
527 root 1.31
528 root 1.8 return 1;
529 elmex 1.1 }
530    
531     /* cast_wonder
532     * wonder is really just a spell that will likely cast another
533     * spell.
534     */
535 root 1.8 int
536     cast_wonder (object *op, object *caster, int dir, object *spell_ob)
537     {
538     object *newspell;
539 elmex 1.1
540 root 1.8 if (!rndm (0, 3))
541     return cast_cone (op, caster, dir, spell_ob);
542 elmex 1.1
543 root 1.8 if (spell_ob->randomitems)
544     {
545     newspell = generate_treasure (spell_ob->randomitems, caster->level);
546     if (!newspell)
547     {
548     LOG (llevError, "cast_wonder: Unable to get a spell!\n");
549     return 0;
550 root 1.5 }
551 root 1.8 if (newspell->type != SPELL)
552     {
553     LOG (llevError, "cast_wonder: spell returned is not a spell (%d, %s)!\n", &newspell->type, &newspell->name);
554     return 0;
555 root 1.5 }
556 root 1.8 /* Prevent inifinit recursion */
557     if (newspell->subtype == SP_WONDER)
558     {
559     LOG (llevError, "cast_wonder: spell returned is another wonder spell!\n");
560     return 0;
561 root 1.5 }
562 root 1.8 return cast_spell (op, caster, dir, newspell, NULL);
563 elmex 1.1 }
564 root 1.8 return 1;
565 elmex 1.1 }
566    
567 root 1.8 int
568     perceive_self (object *op)
569     {
570 root 1.43 const char *cp = describe_item (op, op);
571 root 1.113 archetype *at = archetype::find (shstr_depletion);
572 root 1.8
573 root 1.100 dynbuf_text &buf = msg_dynbuf; buf.clear ();
574 root 1.60
575 root 1.100 if (!op->is_player ())
576     return 0;
577    
578     if (object *race = archetype::find (op->race))
579     buf << " - You are a G<male|female> " << &race->name << ".\n";
580 root 1.60
581     if (object *god = find_god (determine_god (op)))
582 root 1.87 buf << " - You worship " << &god->name << ".\n";
583 root 1.8 else
584 root 1.87 buf << " - You worship no god.\n";
585 root 1.8
586 root 1.60 object *tmp = present_arch_in_ob (at, op);
587 root 1.8
588 root 1.87 if (*cp == '\0' && !tmp)
589     buf << " - You feel very mundane. ";
590 root 1.8 else
591     {
592 root 1.87 buf << " - You have: " << cp << ".\n";
593 root 1.51
594     if (tmp)
595 root 1.60 for (int i = 0; i < NUM_STATS; i++)
596 root 1.51 if (tmp->stats.stat (i) < 0)
597 root 1.87 buf.printf (" - Your %s is depleted by %d.\n", statname[i], -tmp->stats.stat (i));
598 elmex 1.1 }
599    
600 root 1.117 if (op->is_dragon ())
601 root 1.60 /* now grab the 'dragon_ability'-force from the player's inventory */
602     for (tmp = op->inv; tmp; tmp = tmp->below)
603     {
604 root 1.69 if (tmp->type == FORCE && tmp->arch->archname == shstr_dragon_ability_force)
605 root 1.60 {
606     if (tmp->stats.exp == 0)
607 root 1.87 buf << " - Your metabolism isn't focused on anything.\n";
608 root 1.60 else
609 root 1.87 buf << " - Your metabolism is focused on " << change_resist_msg[tmp->stats.exp] << ".\n";
610 root 1.60
611     break;
612     }
613     }
614 root 1.36
615 root 1.100 op->contr->infobox (MSG_CHANNEL ("perceiveself"), buf);
616 root 1.36
617 root 1.8 return 1;
618 elmex 1.1 }
619    
620     /* This creates magic walls. Really, it can create most any object,
621     * within some reason.
622     */
623 root 1.8 int
624     magic_wall (object *op, object *caster, int dir, object *spell_ob)
625     {
626 root 1.27 object *tmp;
627 root 1.8 int i, posblocked, negblocked, maxrange;
628     sint16 x, y;
629 root 1.13 maptile *m;
630 root 1.8 const char *name;
631     archetype *at;
632    
633     if (!dir)
634     {
635     dir = op->facing;
636     x = op->x;
637     y = op->y;
638     }
639     else
640     {
641     x = op->x + freearr_x[dir];
642     y = op->y + freearr_y[dir];
643     }
644 root 1.25
645 root 1.8 m = op->map;
646    
647     if ((spell_ob->move_block || x != op->x || y != op->y) &&
648     (get_map_flags (m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_IS_ALIVE) ||
649     ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) == spell_ob->move_block)))
650     {
651 root 1.125 op->failmsg ("Something is in the way.");
652 root 1.8 return 0;
653     }
654 root 1.25
655 root 1.8 if (spell_ob->other_arch)
656 root 1.116 tmp = spell_ob->other_arch->instance ();
657 root 1.8 else if (spell_ob->race)
658     {
659     char buf1[MAX_BUF];
660    
661     sprintf (buf1, spell_ob->race, dir);
662 root 1.10 at = archetype::find (buf1);
663 root 1.8 if (!at)
664     {
665     LOG (llevError, "summon_wall: Unable to find archetype %s\n", buf1);
666     new_draw_info (NDI_UNIQUE, 0, op, "This spell is broken.");
667     return 0;
668 root 1.5 }
669 root 1.27
670 root 1.116 tmp = at->instance ();
671 root 1.8 }
672     else
673     {
674     LOG (llevError, "magic_wall: spell %s lacks other_arch\n", &spell_ob->name);
675     return 0;
676     }
677    
678     if (tmp->type == SPELL_EFFECT)
679     {
680     tmp->attacktype = spell_ob->attacktype;
681     tmp->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
682     tmp->stats.dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
683     tmp->range = 0;
684     }
685 root 1.124 else if (tmp->flag [FLAG_ALIVE])
686 root 1.8 {
687     tmp->stats.hp = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
688     tmp->stats.maxhp = tmp->stats.hp;
689     }
690 root 1.25
691 root 1.124 if (spell_ob->flag [FLAG_IS_USED_UP] || tmp->flag [FLAG_IS_USED_UP])
692 root 1.8 {
693     tmp->stats.food = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
694 root 1.124 tmp->set_flag (FLAG_IS_USED_UP);
695 elmex 1.1 }
696 root 1.25
697 root 1.124 if (spell_ob->flag [FLAG_TEAR_DOWN])
698 root 1.8 {
699     tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
700     tmp->stats.maxhp = tmp->stats.hp;
701 root 1.124 tmp->set_flag (FLAG_TEAR_DOWN);
702     tmp->set_flag (FLAG_ALIVE);
703 root 1.8 }
704    
705     /* This can't really hurt - if the object doesn't kill anything,
706 root 1.25 * these fields just won't be used. Do not set the owner for
707     * earthwalls, though, so they survive restarts.
708 root 1.8 */
709 root 1.25 if (tmp->type != EARTHWALL) //TODO
710     tmp->set_owner (op);
711    
712 root 1.8 set_spell_skill (op, caster, spell_ob, tmp);
713 root 1.89 tmp->level = casting_level (caster, spell_ob) / 2;
714 elmex 1.1
715 root 1.8 name = tmp->name;
716 root 1.27 if (!(tmp = m->insert (tmp, x, y, op)))
717 root 1.8 {
718     new_draw_info_format (NDI_UNIQUE, 0, op, "Something destroys your %s", name);
719     return 0;
720 elmex 1.1 }
721 root 1.25
722 root 1.8 /* If this is a spellcasting wall, need to insert the spell object */
723 root 1.57 if (tmp->other_arch && tmp->other_arch->type == SPELL)
724 root 1.116 insert_ob_in_ob (tmp->other_arch->instance (), tmp);
725 root 1.8
726     /* This code causes the wall to extend some distance in
727     * each direction, or until an obstruction is encountered.
728     * posblocked and negblocked help determine how far the
729     * created wall can extend, it won't go extend through
730     * blocked spaces.
731     */
732     maxrange = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
733     posblocked = 0;
734     negblocked = 0;
735    
736     for (i = 1; i <= maxrange; i++)
737     {
738     int dir2;
739    
740     dir2 = (dir < 4) ? (dir + 2) : dir - 2;
741    
742     x = tmp->x + i * freearr_x[dir2];
743     y = tmp->y + i * freearr_y[dir2];
744     m = tmp->map;
745    
746     if (!(get_map_flags (m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_IS_ALIVE)) &&
747     ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) != spell_ob->move_block) && !posblocked)
748     {
749 root 1.27 object *tmp2 = tmp->clone ();
750     m->insert (tmp2, x, y, op);
751    
752 root 1.8 /* If this is a spellcasting wall, need to insert the spell object */
753 root 1.57 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
754 root 1.116 tmp2->insert (tmp2->other_arch->instance ());
755 root 1.8
756     }
757     else
758     posblocked = 1;
759    
760     x = tmp->x - i * freearr_x[dir2];
761     y = tmp->y - i * freearr_y[dir2];
762     m = tmp->map;
763    
764     if (!(get_map_flags (m, &m, x, y, &x, &y) & (P_OUT_OF_MAP | P_IS_ALIVE)) &&
765     ((spell_ob->move_block & GET_MAP_MOVE_BLOCK (m, x, y)) != spell_ob->move_block) && !negblocked)
766     {
767 root 1.27 object *tmp2 = tmp->clone ();
768     m->insert (tmp2, x, y, op);
769    
770 root 1.57 if (tmp2->other_arch && tmp2->other_arch->type == SPELL)
771 root 1.116 tmp2->insert (tmp2->other_arch->instance ());
772 root 1.8 }
773     else
774     negblocked = 1;
775 elmex 1.1 }
776    
777 root 1.124 if (tmp->flag [FLAG_BLOCKSVIEW])
778 root 1.8 update_all_los (op->map, op->x, op->y);
779 elmex 1.1
780 root 1.8 return 1;
781 elmex 1.1 }
782    
783 root 1.8 int
784 root 1.104 dimension_door (object *op, object *caster, object *spob, int dir, const char *spellparam)
785 root 1.8 {
786     uint32 dist, maxdist;
787     int mflags;
788 root 1.13 maptile *m;
789 root 1.8 sint16 sx, sy;
790 elmex 1.1
791 root 1.8 if (op->type != PLAYER)
792     return 0;
793 elmex 1.1
794 root 1.8 if (!dir)
795     {
796 root 1.123 op->failmsg ("In what direction?");
797 root 1.8 return 0;
798 elmex 1.1 }
799    
800 root 1.8 /* Given the new outdoor maps, can't let players dimension door for
801     * ever, so put limits in.
802     */
803     maxdist = spob->range + SP_level_range_adjust (caster, spob);
804    
805 root 1.104 if (spellparam)
806 root 1.8 {
807 root 1.104 int count = atoi (spellparam);
808    
809     if (count > maxdist)
810 root 1.8 {
811 root 1.125 op->failmsg ("You can't dimension door that far!");
812 root 1.8 return 0;
813 root 1.5 }
814    
815 root 1.104 for (dist = 0; dist < count; dist++)
816 root 1.8 {
817     mflags = get_map_flags (op->map, &m, op->x + freearr_x[dir] * (dist + 1), op->y + freearr_y[dir] * (dist + 1), &sx, &sy);
818 root 1.5
819 root 1.8 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP))
820     break;
821 root 1.5
822 root 1.8 if ((mflags & P_BLOCKSVIEW) && OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))
823     break;
824 root 1.5 }
825    
826 root 1.104 if (dist < count)
827 root 1.8 {
828     new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the spell.\n");
829     return 0;
830     }
831 root 1.27
832 root 1.8 /* Remove code that puts player on random space on maps. IMO,
833     * a lot of maps probably have areas the player should not get to,
834     * but may not be marked as NO_MAGIC (as they may be bounded
835     * by such squares). Also, there are probably treasure rooms and
836     * lots of other maps that protect areas with no magic, but the
837     * areas themselves don't contain no magic spaces.
838     */
839     /* This call here is really just to normalize the coordinates */
840     mflags = get_map_flags (op->map, &m, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist, &sx, &sy);
841     if (mflags & P_IS_ALIVE || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))
842     {
843     new_draw_info (NDI_UNIQUE, 0, op, "You cast your spell, but nothing happens.\n");
844     return 1; /* Maybe the penalty should be more severe... */
845 root 1.5 }
846 root 1.8 }
847     else
848     {
849     /* Player didn't specify a distance, so lets see how far
850     * we can move the player. Don't know why this stopped on
851     * spaces that blocked the players view.
852     */
853 root 1.5
854 root 1.8 for (dist = 0; dist < maxdist; dist++)
855     {
856     mflags = get_map_flags (op->map, &m, op->x + freearr_x[dir] * (dist + 1), op->y + freearr_y[dir] * (dist + 1), &sx, &sy);
857 root 1.5
858 root 1.8 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP))
859     break;
860 root 1.5
861 root 1.8 if ((mflags & P_BLOCKSVIEW) && OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))
862     break;
863 root 1.5
864     }
865    
866 root 1.8 /* If the destination is blocked, keep backing up until we
867     * find a place for the player.
868     */
869     for (; dist > 0; dist--)
870     {
871     if (get_map_flags (op->map, &m, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist,
872     &sx, &sy) & (P_OUT_OF_MAP | P_IS_ALIVE))
873     continue;
874 root 1.5
875    
876 root 1.8 if (!OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, sx, sy)))
877     break;
878 root 1.5
879     }
880 root 1.8 if (!dist)
881     {
882 root 1.125 op->failmsg ("Your spell failed!\n");
883 root 1.8 return 0;
884 root 1.5 }
885 elmex 1.1 }
886    
887 root 1.8 /* Actually move the player now */
888 root 1.27 if (!(op = op->map->insert (op, op->x + freearr_x[dir] * dist, op->y + freearr_y[dir] * dist, op)))
889 root 1.8 return 1;
890 elmex 1.1
891 root 1.115 op->speed_left = -5. * op->speed; /* Freeze them for a short while */
892 root 1.112
893 root 1.8 return 1;
894 elmex 1.1 }
895    
896     /* cast_heal: Heals something.
897     * op is the caster.
898     * dir is the direction he is casting it in.
899     * spell is the spell object.
900     */
901 root 1.8 int
902     cast_heal (object *op, object *caster, object *spell, int dir)
903     {
904     object *tmp;
905     archetype *at;
906     object *poison;
907     int heal = 0, success = 0;
908    
909     tmp = find_target_for_friendly_spell (op, dir);
910    
911 root 1.40 if (!tmp)
912 root 1.8 return 0;
913    
914     /* Figure out how many hp this spell might cure.
915     * could be zero if this spell heals effects, not damage.
916     */
917     heal = spell->stats.dam;
918     if (spell->stats.hp)
919     heal += random_roll (spell->stats.hp, 6, op, PREFER_HIGH) + spell->stats.hp;
920    
921     if (heal)
922     {
923     if (tmp->stats.hp >= tmp->stats.maxhp)
924 root 1.40 new_draw_info (NDI_UNIQUE, 0, tmp, "You are already fully healed.");
925 root 1.8 else
926     {
927     /* See how many points we actually heal. Instead of messages
928     * based on type of spell, we instead do messages based
929     * on amount of damage healed.
930     */
931 root 1.70 if (heal > tmp->stats.maxhp - tmp->stats.hp)
932 root 1.8 heal = tmp->stats.maxhp - tmp->stats.hp;
933 root 1.70
934 root 1.8 tmp->stats.hp += heal;
935    
936     if (tmp->stats.hp >= tmp->stats.maxhp)
937 root 1.40 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel just fine!");
938 root 1.8 else if (heal > 50)
939 root 1.40 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds close!");
940 root 1.8 else if (heal > 25)
941 root 1.40 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds mostly close.");
942 root 1.8 else if (heal > 10)
943 root 1.40 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to fade.");
944 root 1.8 else
945 root 1.40 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to close.");
946    
947 root 1.8 success = 1;
948     }
949     }
950 root 1.40
951 root 1.8 if (spell->attacktype & AT_DISEASE)
952 root 1.70 if (cure_disease (tmp, op, spell))
953 root 1.8 success = 1;
954    
955     if (spell->attacktype & AT_POISON)
956     {
957 root 1.113 at = archetype::find (shstr_poisoning);
958 root 1.8 poison = present_arch_in_ob (at, tmp);
959     if (poison)
960     {
961     success = 1;
962     new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed");
963     poison->stats.food = 1;
964 root 1.5 }
965 elmex 1.1 }
966 root 1.40
967 root 1.8 if (spell->attacktype & AT_CONFUSION)
968     {
969 root 1.113 poison = present_in_ob_by_name (FORCE, shstr_confusion, tmp);
970 root 1.8 if (poison)
971     {
972     success = 1;
973     new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
974     poison->duration = 1;
975 root 1.5 }
976 elmex 1.1 }
977 root 1.40
978 root 1.8 if (spell->attacktype & AT_BLIND)
979     {
980 root 1.113 at = archetype::find (shstr_blindness);
981 root 1.8 poison = present_arch_in_ob (at, tmp);
982     if (poison)
983     {
984     success = 1;
985     new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return.");
986     poison->stats.food = 1;
987 root 1.5 }
988 elmex 1.1 }
989 root 1.40
990 root 1.8 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp)
991     {
992     tmp->stats.sp += spell->last_sp;
993     if (tmp->stats.sp > tmp->stats.maxsp)
994     tmp->stats.sp = tmp->stats.maxsp;
995     success = 1;
996     new_draw_info (NDI_UNIQUE, 0, tmp, "Magical energy surges through your body!");
997     }
998 root 1.40
999 root 1.8 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace)
1000     {
1001     tmp->stats.grace += spell->last_grace;
1002     if (tmp->stats.grace > tmp->stats.maxgrace)
1003     tmp->stats.grace = tmp->stats.maxgrace;
1004     success = 1;
1005     new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!");
1006 elmex 1.1 }
1007 root 1.40
1008 root 1.122 if (spell->stats.food && tmp->stats.food < MAX_FOOD)
1009 root 1.8 {
1010     tmp->stats.food += spell->stats.food;
1011 root 1.122 min_it (tmp->stats.food, MAX_FOOD);
1012 root 1.70
1013 root 1.8 success = 1;
1014     /* We could do something a bit better like the messages for healing above */
1015     new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food");
1016     }
1017 root 1.40
1018 root 1.8 return success;
1019 elmex 1.1 }
1020    
1021     /* This is used for the spells that gain stats. There are no spells
1022     * right now that icnrease wis/int/pow on a temp basis, so no
1023     * good comments for those.
1024     */
1025 root 1.8 static const char *const no_gain_msgs[NUM_STATS] = {
1026     "You grow no stronger.",
1027     "You grow no more agile.",
1028     "You don't feel any healthier.",
1029 root 1.55 "You didn't grow any more intelligent.",
1030     "You do not feel any wiser.",
1031     "You don't feel any more powerful."
1032 root 1.8 "You are no easier to look at.",
1033 elmex 1.1 };
1034    
1035 root 1.8 int
1036 root 1.105 change_ability_duration (object *spell, object *caster)
1037     {
1038     return spell->duration + SP_level_duration_adjust (caster, spell) * 50;
1039     }
1040    
1041     int
1042 root 1.8 cast_change_ability (object *op, object *caster, object *spell_ob, int dir, int silent)
1043     {
1044 root 1.88 object *force = 0;
1045 root 1.8 int i;
1046    
1047     /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
1048 root 1.27 object *tmp = dir
1049 root 1.88 ? find_target_for_friendly_spell (op, dir)
1050     : op;
1051 root 1.8
1052 root 1.27 if (!tmp)
1053 root 1.8 return 0;
1054    
1055     /* If we've already got a force of this type, don't add a new one. */
1056 root 1.27 for (object *tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1057 root 1.8 {
1058     if (tmp2->type == FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY)
1059     {
1060     if (tmp2->name == spell_ob->name)
1061     {
1062     force = tmp2; /* the old effect will be "refreshed" */
1063     break;
1064 root 1.5 }
1065 root 1.8 else if (spell_ob->race && spell_ob->race == tmp2->name)
1066     {
1067     if (!silent)
1068 root 1.125 op->failmsgf ("You can not cast %s while %s is in effect",
1069     &spell_ob->name, &tmp2->name_pl);
1070 root 1.88
1071 root 1.8 return 0;
1072 root 1.5 }
1073     }
1074 elmex 1.1 }
1075 root 1.88
1076 root 1.108 int duration = change_ability_duration (spell_ob, caster);
1077 root 1.88
1078 root 1.108 if (force)
1079 root 1.8 {
1080     if (duration > force->duration)
1081     {
1082     force->duration = duration;
1083     new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
1084     }
1085     else
1086 root 1.88 new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1087 root 1.55
1088 root 1.8 return 1;
1089     }
1090 root 1.55
1091 root 1.108 new_draw_info_format (NDI_UNIQUE, 0, op,
1092     "You create an aura of magical force. H<The effect will last for about %.10g seconds.>",
1093     TICK2TIME (duration));
1094    
1095     force = get_archetype (FORCE_NAME);
1096     force->subtype = FORCE_CHANGE_ABILITY;
1097     force->duration = duration;
1098    
1099     if (spell_ob->race)
1100     force->name = spell_ob->race;
1101     else
1102     force->name = spell_ob->name;
1103    
1104     force->name_pl = spell_ob->name;
1105    
1106 root 1.8 force->speed = 1.0;
1107     force->speed_left = -1.0;
1108 root 1.124 force->set_flag (FLAG_APPLIED);
1109 root 1.8
1110     /* Now start processing the effects. First, protections */
1111     for (i = 0; i < NROFATTACKS; i++)
1112     {
1113     if (spell_ob->resist[i])
1114     {
1115     force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust (caster, spell_ob);
1116     if (force->resist[i] > 100)
1117     force->resist[i] = 100;
1118 root 1.5 }
1119 elmex 1.1 }
1120 root 1.55
1121 root 1.8 if (spell_ob->stats.hp)
1122     force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust (caster, spell_ob);
1123    
1124     if (tmp->type == PLAYER)
1125     {
1126     /* Stat adjustment spells */
1127     for (i = 0; i < NUM_STATS; i++)
1128     {
1129 root 1.51 if (sint8 stat = spell_ob->stats.stat (i))
1130 root 1.8 {
1131 root 1.51 sint8 sm = 0;
1132     for (sint8 k = 0; k < stat; k++)
1133 root 1.8 sm += rndm (1, 3);
1134    
1135 root 1.51 if (tmp->stats.stat (i) + sm > 15 + 5 * stat)
1136     sm = max (0, (15 + 5 * stat) - tmp->stats.stat (i));
1137    
1138     force->stats.stat (i) = sm;
1139    
1140 root 1.8 if (!sm)
1141     new_draw_info (NDI_UNIQUE, 0, op, no_gain_msgs[i]);
1142 root 1.5 }
1143     }
1144 elmex 1.1 }
1145    
1146 root 1.8 force->move_type = spell_ob->move_type;
1147 elmex 1.1
1148 root 1.124 if (spell_ob->flag [FLAG_SEE_IN_DARK])
1149     force->set_flag (FLAG_SEE_IN_DARK);
1150 elmex 1.1
1151 root 1.124 if (spell_ob->flag [FLAG_XRAYS])
1152     force->set_flag (FLAG_XRAYS);
1153 elmex 1.1
1154 root 1.8 /* Haste/bonus speed */
1155     if (spell_ob->stats.exp)
1156     {
1157     if (op->speed > 0.5f)
1158     force->stats.exp = (sint64) ((float) spell_ob->stats.exp / (op->speed + 0.5f));
1159     else
1160     force->stats.exp = spell_ob->stats.exp;
1161 elmex 1.1 }
1162    
1163 root 1.8 force->stats.wc = spell_ob->stats.wc;
1164     force->stats.ac = spell_ob->stats.ac;
1165     force->attacktype = spell_ob->attacktype;
1166    
1167     insert_ob_in_ob (force, tmp);
1168     change_abil (tmp, force); /* Mostly to display any messages */
1169 root 1.24 tmp->update_stats ();
1170 root 1.55
1171 root 1.8 return 1;
1172 elmex 1.1 }
1173    
1174     /* This used to be part of cast_change_ability, but it really didn't make
1175     * a lot of sense, since most of the values it derives are from the god
1176     * of the caster.
1177     */
1178 root 1.8 int
1179     cast_bless (object *op, object *caster, object *spell_ob, int dir)
1180     {
1181     int i;
1182 root 1.85 object *god = find_god (determine_god (op)), *force = NULL, *tmp;
1183 root 1.8
1184     /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
1185     if (dir != 0)
1186     {
1187     tmp = find_target_for_friendly_spell (op, dir);
1188 root 1.85
1189     if (!tmp)
1190     return 0;
1191 root 1.8 }
1192     else
1193 root 1.85 tmp = op;
1194 root 1.8
1195     /* If we've already got a force of this type, don't add a new one. */
1196 root 1.85 for (object *tmp2 = tmp->inv; tmp2; tmp2 = tmp2->below)
1197 root 1.8 {
1198     if (tmp2->type == FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY)
1199     {
1200     if (tmp2->name == spell_ob->name)
1201     {
1202     force = tmp2; /* the old effect will be "refreshed" */
1203     break;
1204 root 1.5 }
1205 root 1.8 else if (spell_ob->race && spell_ob->race == tmp2->name)
1206     {
1207     new_draw_info_format (NDI_UNIQUE, 0, op, "You can not cast %s while %s is in effect", &spell_ob->name, &tmp2->name_pl);
1208     return 0;
1209 root 1.5 }
1210     }
1211 elmex 1.1 }
1212 root 1.85
1213 root 1.8 if (force == NULL)
1214     {
1215     force = get_archetype (FORCE_NAME);
1216     force->subtype = FORCE_CHANGE_ABILITY;
1217     if (spell_ob->race)
1218     force->name = spell_ob->race;
1219     else
1220     force->name = spell_ob->name;
1221     force->name_pl = spell_ob->name;
1222     new_draw_info (NDI_UNIQUE, 0, op, "You create an aura of magical force.");
1223     }
1224     else
1225     {
1226     int duration;
1227    
1228     duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50;
1229     if (duration > force->duration)
1230     {
1231     force->duration = duration;
1232     new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
1233 root 1.5 }
1234 root 1.8 else
1235     {
1236     new_draw_info (NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1237     }
1238     return 0;
1239 elmex 1.1 }
1240 root 1.8 force->duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob) * 50;
1241     force->speed = 1.0;
1242     force->speed_left = -1.0;
1243 root 1.124 force->set_flag (FLAG_APPLIED);
1244 elmex 1.1
1245 root 1.8 if (!god)
1246     {
1247     new_draw_info (NDI_UNIQUE, 0, op, "Your blessing seems empty.");
1248     }
1249     else
1250     {
1251     /* Only give out good benefits, and put a max on it */
1252     for (i = 0; i < NROFATTACKS; i++)
1253 root 1.113 if (god->resist[i] > 0)
1254     force->resist[i] = min (god->resist[i], spell_ob->resist[ATNR_GODPOWER]);
1255    
1256 root 1.8 force->path_attuned |= god->path_attuned;
1257 root 1.7
1258 root 1.8 if (spell_ob->attacktype)
1259     force->slaying = god->slaying;
1260 root 1.7
1261 root 1.8 if (tmp != op)
1262     {
1263     new_draw_info_format (NDI_UNIQUE, 0, op, "You bless %s.", &tmp->name);
1264     new_draw_info_format (NDI_UNIQUE, 0, tmp, "%s blessed you.", &op->name);
1265     }
1266     else
1267     {
1268     new_draw_info_format (NDI_UNIQUE, 0, tmp, "You are blessed by %s!", &god->name);
1269 root 1.5 }
1270 elmex 1.1
1271     }
1272 root 1.8 force->stats.wc = spell_ob->stats.wc;
1273     force->stats.ac = spell_ob->stats.ac;
1274 elmex 1.1
1275 root 1.8 change_abil (tmp, force); /* Mostly to display any messages */
1276     insert_ob_in_ob (force, tmp);
1277 root 1.24 tmp->update_stats ();
1278 root 1.8 return 1;
1279 elmex 1.1 }
1280    
1281     /* Alchemy code by Mark Wedel
1282     *
1283     * This code adds a new spell, called alchemy. Alchemy will turn
1284 root 1.66 * objects to pyrite ("false gold"), henceforth called gold nuggets.
1285     *
1286     * The value of the gold nuggets being about 90% of that of the item
1287     * itself. It uses the value of the object before charisma adjustments,
1288     * because the nuggets themselves will be will be adjusted by charisma
1289     * when sold.
1290 elmex 1.1 *
1291     * There is also a chance (1:30) that you will get nothing at all
1292     * for the object. There is also a maximum weight that will be
1293 root 1.37 * alchemised.
1294 elmex 1.1 */
1295 root 1.8 static void
1296 root 1.38 alchemy_object (object *obj, uint64 &total_value, int &total_weight)
1297 root 1.8 {
1298     uint64 value = query_cost (obj, NULL, F_TRUE);
1299    
1300 root 1.75 /* Give third price when we alchemy money (this should hopefully
1301 root 1.8 * make it so that it isn't worth it to alchemy money, sell
1302     * the nuggets, alchemy the gold from that, etc.
1303     * Otherwise, give 9 silver on the gold for other objects,
1304     * so that it would still be more affordable to haul
1305     * the stuff back to town.
1306     */
1307 root 1.124 if (obj->flag [FLAG_UNPAID])
1308 root 1.8 value = 0;
1309     else if (obj->type == MONEY || obj->type == GEM)
1310     value /= 3;
1311     else
1312 root 1.39 value = value * 9 / 10;
1313 root 1.8
1314 root 1.37 if (obj->value > 0 && rndm (0, 29))
1315 root 1.38 total_value += value;
1316 root 1.8
1317 root 1.38 total_weight += obj->total_weight ();
1318 root 1.8
1319 root 1.91 obj->destroy ();
1320 root 1.8 }
1321    
1322     int
1323     alchemy (object *op, object *caster, object *spell_ob)
1324 elmex 1.1 {
1325 root 1.8 if (op->type != PLAYER)
1326     return 0;
1327    
1328 root 1.66 archetype *nugget[3];
1329    
1330 root 1.113 nugget[0] = archetype::find (shstr_pyrite3);
1331     nugget[1] = archetype::find (shstr_pyrite2);
1332     nugget[2] = archetype::find (shstr_pyrite);
1333 root 1.39
1334 root 1.38 /* Put a maximum weight of items that can be alchemised. Limits the power
1335     * some, and also prevents people from alchemising every table/chair/clock
1336 root 1.8 * in sight
1337     */
1338 root 1.38 int duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
1339     int weight_max = duration * 1000;
1340     uint64 value_max = duration * 1000;
1341 elmex 1.1
1342 root 1.39 int weight = 0;
1343 root 1.38
1344     for (int y = op->y - 1; y <= op->y + 1; y++)
1345 root 1.8 {
1346 root 1.38 for (int x = op->x - 1; x <= op->x + 1; x++)
1347 root 1.8 {
1348 root 1.38 uint64 value = 0;
1349    
1350     sint16 nx = x;
1351     sint16 ny = y;
1352 elmex 1.1
1353 root 1.39 maptile *mp = op->map;
1354 root 1.5
1355 root 1.39 int mflags = get_map_flags (mp, &mp, nx, ny, &nx, &ny);
1356 root 1.5
1357 root 1.8 if (mflags & (P_OUT_OF_MAP | P_NO_MAGIC))
1358     continue;
1359    
1360     /* Treat alchemy a little differently - most spell effects
1361     * use fly as the movement type - for alchemy, consider it
1362     * ground level effect.
1363     */
1364     if (GET_MAP_MOVE_BLOCK (mp, nx, ny) & MOVE_WALK)
1365     continue;
1366    
1367 root 1.38 for (object *next, *tmp = mp->at (nx, ny).bot; tmp; tmp = next)
1368 root 1.8 {
1369     next = tmp->above;
1370 root 1.37
1371 root 1.124 if (tmp->weight > 0 && !tmp->flag [FLAG_NO_PICK] &&
1372     !tmp->flag [FLAG_ALIVE] && !tmp->flag [FLAG_IS_CAULDRON])
1373 root 1.8 {
1374     if (tmp->inv)
1375     {
1376     object *next1, *tmp1;
1377    
1378 root 1.37 for (tmp1 = tmp->inv; tmp1; tmp1 = next1)
1379 root 1.8 {
1380     next1 = tmp1->below;
1381 root 1.124 if (tmp1->weight > 0 && !tmp1->flag [FLAG_NO_PICK] &&
1382     !tmp1->flag [FLAG_ALIVE] && !tmp1->flag [FLAG_IS_CAULDRON])
1383 root 1.38 alchemy_object (tmp1, value, weight);
1384 root 1.5 }
1385     }
1386 root 1.37
1387 root 1.38 alchemy_object (tmp, value, weight);
1388 root 1.8
1389     if (weight > weight_max)
1390 root 1.38 break;
1391     }
1392     }
1393    
1394 root 1.66 value -= rndm (value >> 4);
1395 root 1.38 value = min (value, value_max);
1396    
1397 root 1.66 for (int i = 0; i < sizeof (nugget) / sizeof (nugget [0]); ++i)
1398     if (int nrof = value / nugget [i]->value)
1399     {
1400     value -= nrof * nugget[i]->value;
1401    
1402 root 1.116 object *tmp = nugget[i]->instance ();
1403 root 1.66 tmp->nrof = nrof;
1404     tmp->flag [FLAG_IDENTIFIED] = true;
1405 root 1.67 op->map->insert (tmp, x, y, op, 0);
1406 root 1.66 }
1407 root 1.38
1408     if (weight > weight_max)
1409     goto bailout;
1410 root 1.8 }
1411     }
1412 root 1.17
1413 root 1.38 bailout:
1414 root 1.8 return 1;
1415 elmex 1.1 }
1416    
1417     /* This function removes the cursed/damned status on equipped
1418     * items.
1419     */
1420 root 1.8 int
1421     remove_curse (object *op, object *caster, object *spell)
1422     {
1423     int success = 0, was_one = 0;
1424    
1425 root 1.106 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1426 root 1.124 if (tmp->flag [FLAG_APPLIED] &&
1427     ((tmp->flag [FLAG_CURSED] && spell->flag [FLAG_CURSED]) ||
1428     (tmp->flag [FLAG_DAMNED] && spell->flag [FLAG_DAMNED])))
1429 root 1.8 {
1430     was_one++;
1431 root 1.80
1432 root 1.89 if (tmp->level <= casting_level (caster, spell))
1433 root 1.8 {
1434     success++;
1435 root 1.124 if (spell->flag [FLAG_DAMNED])
1436     tmp->clr_flag (FLAG_DAMNED);
1437 root 1.8
1438 root 1.124 tmp->clr_flag (FLAG_CURSED);
1439     tmp->clr_flag (FLAG_KNOWN_CURSED);
1440 root 1.8 tmp->value = 0; /* Still can't sell it */
1441 root 1.80
1442     if (object *pl = tmp->visible_to ())
1443     esrv_update_item (UPD_FLAGS, pl, tmp);
1444 root 1.8 }
1445     }
1446    
1447     if (op->type == PLAYER)
1448     {
1449     if (success)
1450 root 1.38 new_draw_info (NDI_UNIQUE, 0, op, "You feel like some of your items are looser now.");
1451 root 1.8 else
1452     {
1453     if (was_one)
1454     new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove the curse.");
1455     else
1456     new_draw_info (NDI_UNIQUE, 0, op, "You are not using any cursed items.");
1457 root 1.5 }
1458 elmex 1.1 }
1459 root 1.21
1460 root 1.8 return success;
1461 elmex 1.1 }
1462    
1463     /* Identifies objects in the players inventory/on the ground */
1464 root 1.8 int
1465     cast_identify (object *op, object *caster, object *spell)
1466     {
1467     object *tmp;
1468 root 1.100 dynbuf_text &buf = msg_dynbuf; buf.clear ();
1469 root 1.8
1470 root 1.101 int num_ident = max (1, spell->stats.dam + SP_level_dam_adjust (caster, spell));
1471 root 1.8
1472     for (tmp = op->inv; tmp; tmp = tmp->below)
1473     {
1474 root 1.124 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && need_identify (tmp))
1475 root 1.8 {
1476     identify (tmp);
1477 root 1.21
1478 root 1.8 if (op->type == PLAYER)
1479     {
1480 root 1.87 buf.printf ("You identified: %s.\r", long_desc (tmp, op));
1481 root 1.21
1482 root 1.8 if (tmp->msg)
1483 root 1.87 buf << "The item has a story:\r" << tmp->msg << "\n\n";
1484 root 1.5 }
1485 root 1.21
1486 root 1.101 if (!--num_ident)
1487 root 1.8 break;
1488 root 1.5 }
1489 elmex 1.1 }
1490 root 1.21
1491 root 1.8 /* If all the power of the spell has been used up, don't go and identify
1492     * stuff on the floor. Only identify stuff on the floor if the spell
1493     * was not fully used.
1494     */
1495     if (num_ident)
1496     {
1497 root 1.48 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp; tmp = tmp->above)
1498 root 1.124 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && need_identify (tmp))
1499 root 1.8 {
1500 root 1.21 identify (tmp);
1501 root 1.8
1502 root 1.80 if (object *pl = tmp->visible_to ())
1503 root 1.8 {
1504 root 1.87 buf.printf ("On the ground you identified: %s.\r", long_desc (tmp, op));
1505 root 1.21
1506 root 1.8 if (tmp->msg)
1507 root 1.87 buf << "The item has a story:\r" << tmp->msg << "\n\n";
1508 root 1.8 }
1509 root 1.21
1510 root 1.101 if (!--num_ident)
1511 root 1.8 break;
1512     }
1513     }
1514 root 1.21
1515 root 1.73 if (buf.empty ())
1516     {
1517     op->failmsg ("You can't reach anything unidentified.");
1518     return 0;
1519     }
1520 root 1.8 else
1521 root 1.73 {
1522     if (op->contr)
1523     op->contr->infobox (MSG_CHANNEL ("identify"), buf);
1524 root 1.21
1525 root 1.73 spell_effect (spell, op->x, op->y, op->map, op);
1526     return 1;
1527     }
1528 elmex 1.1 }
1529    
1530 root 1.8 int
1531     cast_detection (object *op, object *caster, object *spell, object *skill)
1532     {
1533     object *tmp, *last, *god, *detect;
1534     int done_one, range, mflags, floor, level;
1535     sint16 x, y, nx, ny;
1536 root 1.13 maptile *m;
1537 root 1.8
1538     /* We precompute some values here so that we don't have to keep
1539     * doing it over and over again.
1540     */
1541     god = find_god (determine_god (op));
1542 root 1.89 level = casting_level (caster, spell);
1543 root 1.8 range = spell->range + SP_level_range_adjust (caster, spell);
1544    
1545     if (!skill)
1546     skill = caster;
1547    
1548 root 1.118 dynbuf buf;
1549     unordered_mapwalk (buf, op, -range, -range, range, range)
1550 root 1.98 {
1551     /* For most of the detections, we only detect objects above the
1552     * floor. But this is not true for show invisible.
1553     * Basically, we just go and find the top object and work
1554     * down - that is easier than working up.
1555     */
1556    
1557     for (last = NULL, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above)
1558     last = tmp;
1559    
1560     /* Shouldn't happen, but if there are no objects on a space, this
1561     * would happen.
1562     */
1563     if (!last)
1564     continue;
1565    
1566     done_one = 0;
1567     floor = 0;
1568     detect = NULL;
1569     for (tmp = last; tmp; tmp = tmp->below)
1570     {
1571     /* show invisible */
1572 root 1.124 if (spell->flag [FLAG_MAKE_INVIS]
1573 root 1.98 /* Might there be other objects that we can make visible? */
1574 root 1.124 && (tmp->invisible && (tmp->flag [FLAG_MONSTER]
1575     || (tmp->type == PLAYER && !tmp->flag [FLAG_WIZ])
1576 elmex 1.121 || tmp->type == T_HANDLE
1577     || tmp->type == TRAPDOOR
1578     || tmp->type == EXIT
1579     || tmp->type == HOLE
1580     || tmp->type == BUTTON
1581     || tmp->type == TELEPORTER
1582     || tmp->type == GATE
1583     || tmp->type == LOCKED_DOOR
1584     || tmp->type == WEAPON
1585     || tmp->type == ALTAR
1586     || tmp->type == SIGN
1587     || tmp->type == TRIGGER_PEDESTAL
1588     || tmp->type == SPECIAL_KEY
1589     || tmp->type == TREASURE
1590     || tmp->type == BOOK
1591     || tmp->type == HOLY_ALTAR
1592     || tmp->type == CONTAINER)))
1593 root 1.98 {
1594     if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4)
1595     {
1596     tmp->invisible = 0;
1597     done_one = 1;
1598     }
1599     }
1600    
1601 root 1.124 if (tmp->flag [FLAG_IS_FLOOR])
1602 root 1.98 floor = 1;
1603    
1604     /* All detections below this point don't descend beneath the floor,
1605     * so just continue on. We could be clever and look at the type of
1606     * detection to completely break out if we don't care about objects beneath
1607     * the floor, but once we get to the floor, not likely a very big issue anyways.
1608     */
1609     if (floor)
1610     continue;
1611    
1612     /* I had thought about making detect magic and detect curse
1613     * show the flash the magic item like it does for detect monster.
1614     * however, if the object is within sight, this would then make it
1615     * difficult to see what object is magical/cursed, so the
1616     * effect wouldn't be as apparent.
1617     */
1618    
1619     /* detect magic */
1620 root 1.124 if (spell->flag [FLAG_KNOWN_MAGICAL] &&
1621     !tmp->flag [FLAG_KNOWN_MAGICAL] && !tmp->flag [FLAG_IDENTIFIED] && is_magical (tmp))
1622 root 1.98 {
1623 root 1.124 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1624 elmex 1.121 /* make runes more visible */
1625 root 1.98 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC)
1626     tmp->stats.Cha /= 4;
1627    
1628     done_one = 1;
1629     }
1630    
1631     /* detect monster */
1632 root 1.124 if (spell->flag [FLAG_MONSTER] && (tmp->flag [FLAG_MONSTER] || tmp->type == PLAYER))
1633 root 1.98 {
1634     done_one = 2;
1635    
1636     if (!detect)
1637     detect = tmp;
1638     }
1639    
1640     /* Basically, if race is set in the spell, then the creatures race must
1641     * match that. if the spell race is set to GOD, then the gods opposing
1642     * race must match.
1643     */
1644 root 1.124 if (spell->race && tmp->flag [FLAG_MONSTER] && tmp->race &&
1645 root 1.98 ((spell->race == shstr_GOD && god && god->slaying.contains (tmp->race)) ||
1646     spell->race.contains (tmp->race)))
1647     {
1648     done_one = 2;
1649    
1650     if (!detect)
1651     detect = tmp;
1652     }
1653 root 1.21
1654 root 1.124 if (spell->flag [FLAG_KNOWN_CURSED] && !tmp->flag [FLAG_KNOWN_CURSED] &&
1655     (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1656 root 1.98 {
1657 root 1.124 tmp->set_flag (FLAG_KNOWN_CURSED);
1658 root 1.98 done_one = 1;
1659     }
1660 elmex 1.121
1661     // Do mining detection spell:
1662     if (spell->last_sp == 1) // 1 - detect any vein
1663     {
1664     if (tmp->type == VEIN)
1665     {
1666     if (tmp->other_arch)
1667     {
1668     if (!detect)
1669     detect = tmp->other_arch;
1670     done_one = 2;
1671     }
1672     else
1673     done_one = 1;
1674     }
1675     }
1676 root 1.98 } /* for stack of objects on this space */
1677 elmex 1.1
1678 root 1.98 /* Code here puts an effect of the spell on the space, so you can see
1679     * where the magic is.
1680     */
1681     if (done_one)
1682     {
1683 root 1.116 object *detect_ob = spell->other_arch->instance ();
1684 root 1.8
1685 root 1.98 /* if this is set, we want to copy the face */
1686     if (done_one == 2 && detect)
1687     {
1688     detect_ob->face = detect->face;
1689     detect_ob->animation_id = detect->animation_id;
1690     detect_ob->anim_speed = detect->anim_speed;
1691     detect_ob->last_anim = 0;
1692     /* by default, the detect_ob is already animated */
1693 root 1.124 if (!detect->flag [FLAG_ANIMATE])
1694     detect_ob->clr_flag (FLAG_ANIMATE);
1695 root 1.98 }
1696 root 1.27
1697 elmex 1.121 m->insert (detect_ob, nx, ny, op, INS_ON_TOP);
1698 root 1.98 }
1699     } /* for processing the surrounding spaces */
1700 root 1.5
1701    
1702 root 1.8 /* Now process objects in the players inventory if detect curse or magic */
1703 root 1.124 if (spell->flag [FLAG_KNOWN_CURSED] || spell->flag [FLAG_KNOWN_MAGICAL])
1704 root 1.8 {
1705     done_one = 0;
1706 root 1.80
1707 root 1.8 for (tmp = op->inv; tmp; tmp = tmp->below)
1708     {
1709 root 1.124 if (!tmp->invisible && !tmp->flag [FLAG_IDENTIFIED])
1710 root 1.8 {
1711 root 1.124 if (spell->flag [FLAG_KNOWN_MAGICAL] && is_magical (tmp) && !tmp->flag [FLAG_KNOWN_MAGICAL])
1712 root 1.8 {
1713 root 1.124 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1714 root 1.80
1715     if (object *pl = tmp->visible_to ())
1716     esrv_update_item (UPD_FLAGS, pl, tmp);
1717 root 1.5 }
1718 root 1.80
1719 root 1.124 if (spell->flag [FLAG_KNOWN_CURSED] && !tmp->flag [FLAG_KNOWN_CURSED] &&
1720     (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1721 root 1.8 {
1722 root 1.124 tmp->set_flag (FLAG_KNOWN_CURSED);
1723 root 1.80
1724     if (object *pl = tmp->visible_to ())
1725     esrv_update_item (UPD_FLAGS, pl, tmp);
1726 root 1.5 }
1727 root 1.8 } /* if item is not identified */
1728     } /* for the players inventory */
1729     } /* if detect magic/curse and object is a player */
1730 root 1.80
1731 root 1.8 return 1;
1732 elmex 1.1 }
1733    
1734    
1735     /**
1736     * Checks if victim has overcharged mana. caster_level is the caster's (skill)
1737     * level whos spell did cause the overcharge.
1738     */
1739 root 1.8 static void
1740     charge_mana_effect (object *victim, int caster_level)
1741 elmex 1.1 {
1742    
1743 root 1.8 /* Prevent explosions for objects without mana. Without this check, doors
1744     * will explode, too.
1745     */
1746     if (victim->stats.maxsp <= 0)
1747     return;
1748 elmex 1.1
1749 root 1.8 new_draw_info (NDI_UNIQUE, 0, victim, "You feel energy course through you.");
1750 elmex 1.1
1751 root 1.8 if (victim->stats.sp >= victim->stats.maxsp * 2)
1752     {
1753     new_draw_info (NDI_UNIQUE, 0, victim, "Your head explodes!");
1754     victim->stats.sp = 2 * victim->stats.maxsp;
1755 elmex 1.99 create_exploding_ball_at (victim, caster_level);
1756 elmex 1.1 }
1757 root 1.8 else if (victim->stats.sp >= victim->stats.maxsp * 1.88)
1758 root 1.86 new_draw_info (NDI_UNIQUE | NDI_ORANGE, 0, victim, "You feel like your head is going to explode.");
1759 root 1.8 else if (victim->stats.sp >= victim->stats.maxsp * 1.66)
1760 root 1.27 new_draw_info (NDI_UNIQUE, 0, victim, "You get a splitting headache!");
1761 root 1.8 else if (victim->stats.sp >= victim->stats.maxsp * 1.5)
1762     {
1763     new_draw_info (NDI_UNIQUE, 0, victim, "Chaos fills your world.");
1764     confuse_player (victim, victim, 99);
1765 elmex 1.1 }
1766 root 1.8 else if (victim->stats.sp >= victim->stats.maxsp * 1.25)
1767 root 1.27 new_draw_info (NDI_UNIQUE, 0, victim, "You start hearing voices.");
1768 elmex 1.1 }
1769    
1770     /* cast_transfer
1771     * This spell transfers sp from the player to another person.
1772     * We let the target go above their normal maximum SP.
1773     */
1774    
1775 root 1.8 int
1776     cast_transfer (object *op, object *caster, object *spell, int dir)
1777     {
1778     object *plyr = NULL;
1779     sint16 x, y;
1780 root 1.13 maptile *m;
1781 root 1.8 int mflags;
1782    
1783     m = op->map;
1784     x = op->x + freearr_x[dir];
1785     y = op->y + freearr_y[dir];
1786    
1787     mflags = get_map_flags (m, &m, x, y, &x, &y);
1788    
1789     if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
1790     {
1791 root 1.22 for (plyr = GET_MAP_OB (m, x, y); plyr != NULL; plyr = plyr->above)
1792 root 1.124 if (plyr != op && plyr->flag [FLAG_ALIVE])
1793 root 1.8 break;
1794 elmex 1.1 }
1795    
1796    
1797 root 1.8 /* If we did not find a player in the specified direction, transfer
1798     * to anyone on top of us. This is used for the rune of transference mostly.
1799     */
1800     if (plyr == NULL)
1801 root 1.22 for (plyr = GET_MAP_OB (op->map, op->x, op->y); plyr != NULL; plyr = plyr->above)
1802 root 1.124 if (plyr != op && plyr->flag [FLAG_ALIVE])
1803 root 1.8 break;
1804 elmex 1.1
1805 root 1.8 if (!plyr)
1806     {
1807 root 1.125 op->failmsg ("There is no one there.");
1808 root 1.8 return 0;
1809 elmex 1.1 }
1810 root 1.8 /* give sp */
1811     if (spell->stats.dam > 0)
1812     {
1813     plyr->stats.sp += spell->stats.dam + SP_level_dam_adjust (caster, spell);
1814 root 1.89 charge_mana_effect (plyr, casting_level (caster, spell));
1815 root 1.8 return 1;
1816 elmex 1.1 }
1817 root 1.8 /* suck sp away. Can't suck sp from yourself */
1818     else if (op != plyr)
1819     {
1820     /* old dragin magic used floats. easier to just use ints and divide by 100 */
1821    
1822     int rate = -spell->stats.dam + SP_level_dam_adjust (caster, spell), sucked;
1823    
1824     if (rate > 95)
1825     rate = 95;
1826    
1827     sucked = (plyr->stats.sp * rate) / 100;
1828     plyr->stats.sp -= sucked;
1829 root 1.124 if (op->flag [FLAG_ALIVE])
1830 root 1.8 {
1831     /* Player doesn't get full credit */
1832     sucked = (sucked * rate) / 100;
1833     op->stats.sp += sucked;
1834     if (sucked > 0)
1835     {
1836 root 1.89 charge_mana_effect (op, casting_level (caster, spell));
1837 root 1.5 }
1838     }
1839 root 1.8 return 1;
1840 elmex 1.1 }
1841 root 1.8 return 0;
1842 elmex 1.1 }
1843    
1844    
1845     /* counterspell: nullifies spell effects.
1846     * op is the counterspell object, dir is the direction
1847     * it was cast in.
1848     * Basically, if the object has a magic attacktype,
1849     * this may nullify it.
1850     */
1851 root 1.8 void
1852     counterspell (object *op, int dir)
1853 elmex 1.1 {
1854 root 1.8 object *tmp, *head, *next;
1855     int mflags;
1856 root 1.13 maptile *m;
1857 root 1.8 sint16 sx, sy;
1858    
1859     sx = op->x + freearr_x[dir];
1860     sy = op->y + freearr_y[dir];
1861     m = op->map;
1862     mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1863     if (mflags & P_OUT_OF_MAP)
1864     return;
1865 elmex 1.1
1866 root 1.22 for (tmp = GET_MAP_OB (m, sx, sy); tmp != NULL; tmp = next)
1867 root 1.8 {
1868     next = tmp->above;
1869 elmex 1.1
1870 root 1.8 /* Need to look at the head object - otherwise, if tmp
1871     * points to a monster, we don't have all the necessary
1872     * info for it.
1873     */
1874     if (tmp->head)
1875     head = tmp->head;
1876     else
1877     head = tmp;
1878    
1879     /* don't attack our own spells */
1880     if (tmp->owner && tmp->owner == op->owner)
1881     continue;
1882    
1883     /* Basically, if the object is magical and not counterspell,
1884     * we will more or less remove the object. Don't counterspell
1885     * monsters either.
1886     */
1887 elmex 1.1
1888 elmex 1.44 if (head->attacktype & AT_MAGIC
1889     && !(head->attacktype & AT_COUNTERSPELL)
1890 root 1.124 && !head->flag [FLAG_MONSTER]
1891 elmex 1.44 && (op->level > head->level))
1892 root 1.91 head->destroy ();
1893 root 1.8 else
1894     switch (head->type)
1895     {
1896     case SPELL_EFFECT:
1897 elmex 1.44 // XXX: Don't affect floor spelleffects. See also XXX comment
1898     // about sanctuary in spell_util.C
1899 root 1.124 if (tmp->flag [FLAG_IS_FLOOR])
1900 elmex 1.44 continue;
1901    
1902 root 1.8 if (op->level > head->level)
1903 root 1.91 head->destroy ();
1904 root 1.17
1905 root 1.5 break;
1906    
1907 root 1.8 /* I really don't get this rune code that much - that
1908     * random chance seems really low.
1909     */
1910     case RUNE:
1911     if (rndm (0, 149) == 0)
1912     {
1913     head->stats.hp--; /* weaken the rune */
1914     if (!head->stats.hp)
1915 root 1.91 head->destroy ();
1916 root 1.8 }
1917 root 1.5 break;
1918 root 1.8 }
1919 elmex 1.1 }
1920     }
1921    
1922     /* cast_consecrate() - a spell to make an altar your god's */
1923 root 1.8 int
1924     cast_consecrate (object *op, object *caster, object *spell)
1925     {
1926     char buf[MAX_BUF];
1927 elmex 1.1
1928 root 1.8 object *tmp, *god = find_god (determine_god (op));
1929 elmex 1.1
1930 root 1.8 if (!god)
1931     {
1932 root 1.125 op->failmsg ("You can't consecrate anything if you don't worship a god!");
1933 root 1.8 return 0;
1934 elmex 1.1 }
1935 root 1.8
1936     for (tmp = op->below; tmp; tmp = tmp->below)
1937     {
1938 root 1.124 if (tmp->flag [FLAG_IS_FLOOR])
1939 root 1.8 break;
1940     if (tmp->type == HOLY_ALTAR)
1941     {
1942    
1943 root 1.89 if (tmp->level > casting_level (caster, spell))
1944 root 1.8 {
1945 root 1.125 op->failmsgf ("You are not powerful enough to reconsecrate the %s", &tmp->name);
1946 root 1.8 return 0;
1947     }
1948     else
1949     {
1950     /* If we got here, we are consecrating an altar */
1951     sprintf (buf, "Altar of %s", &god->name);
1952     tmp->name = buf;
1953 root 1.89 tmp->level = casting_level (caster, spell);
1954 root 1.8 tmp->other_arch = god->arch;
1955 root 1.80
1956 root 1.8 if (op->type == PLAYER)
1957     esrv_update_item (UPD_NAME, op, tmp);
1958 root 1.80
1959 root 1.8 new_draw_info_format (NDI_UNIQUE, 0, op, "You consecrated the altar to %s!", &god->name);
1960     return 1;
1961 root 1.5 }
1962     }
1963 elmex 1.1 }
1964 root 1.125
1965     op->failmsg ("You are not standing over an altar!");
1966 root 1.8 return 0;
1967 elmex 1.1 }
1968    
1969     /* animate_weapon -
1970     * Generalization of staff_to_snake. Makes a golem out of the caster's weapon.
1971     * The golem is based on the archetype specified, modified by the caster's level
1972     * and the attributes of the weapon. The weapon is inserted in the golem's
1973     * inventory so that it falls to the ground when the golem dies.
1974     * This code was very odd - code early on would only let players use the spell,
1975     * yet the code wass full of player checks. I've presumed that the code
1976     * that only let players use it was correct, and removed all the other
1977     * player checks. MSW 2003-01-06
1978     */
1979 root 1.8 int
1980     animate_weapon (object *op, object *caster, object *spell, int dir)
1981     {
1982     object *weapon, *tmp;
1983     char buf[MAX_BUF];
1984     int a, i;
1985     sint16 x, y;
1986 root 1.13 maptile *m;
1987 root 1.8
1988     if (!spell->other_arch)
1989     {
1990     new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
1991     LOG (llevError, "animate_weapon failed: spell %s missing other_arch!\n", &spell->name);
1992     return 0;
1993 elmex 1.1 }
1994 root 1.8 /* exit if it's not a player using this spell. */
1995     if (op->type != PLAYER)
1996     return 0;
1997 elmex 1.1
1998 root 1.8 /* if player already has a golem, abort */
1999 root 1.49 if (object *golem = op->contr->golem)
2000 root 1.8 {
2001 root 1.46 control_golem (golem, dir);
2002 root 1.8 return 0;
2003 elmex 1.1 }
2004    
2005 root 1.8 /* if no direction specified, pick one */
2006     if (!dir)
2007 root 1.84 dir = find_free_spot (spell->other_arch, op->map, op->x, op->y, 1, 9);
2008 root 1.8
2009     m = op->map;
2010     x = op->x + freearr_x[dir];
2011     y = op->y + freearr_y[dir];
2012    
2013     /* if there's no place to put the golem, abort */
2014 root 1.84 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP)
2015     || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type))
2016 root 1.8 {
2017 root 1.125 op->failmsg ("There is something in the way.");
2018 root 1.8 return 0;
2019 elmex 1.1 }
2020    
2021 root 1.8 /* Use the weapon marked by the player. */
2022     weapon = find_marked_object (op);
2023 elmex 1.1
2024 root 1.8 if (!weapon)
2025     {
2026 root 1.125 op->failmsg ("You must mark a weapon to use with this spell!");
2027 root 1.8 return 0;
2028     }
2029 root 1.93
2030     if (spell->race && weapon->arch->archname != spell->race)
2031 root 1.8 {
2032 root 1.125 op->failmsg ("The spell fails to transform your weapon.");
2033 root 1.8 return 0;
2034     }
2035 root 1.93
2036 root 1.8 if (weapon->type != WEAPON)
2037     {
2038 root 1.125 op->failmsg ("You need to wield a weapon to animate it.");
2039 root 1.8 return 0;
2040 elmex 1.1 }
2041 root 1.93
2042 root 1.124 if (weapon->flag [FLAG_APPLIED])
2043 root 1.8 {
2044 root 1.125 op->failmsgf ("You need to unequip %s before using it in this spell", query_name (weapon));
2045 root 1.8 return 0;
2046 elmex 1.1 }
2047 root 1.8
2048 root 1.80 weapon = weapon->split ();
2049 root 1.8
2050     /* create the golem object */
2051 root 1.116 tmp = spell->other_arch->instance ();
2052 root 1.8
2053     /* if animated by a player, give the player control of the golem */
2054 root 1.124 tmp->clr_flag (FLAG_MONSTER);
2055 root 1.8 tmp->stats.exp = 0;
2056     add_friendly_object (tmp);
2057     tmp->type = GOLEM;
2058 root 1.19 tmp->set_owner (op);
2059 root 1.49 op->contr->golem = tmp;
2060 root 1.46 set_spell_skill (op, caster, spell, tmp);
2061 root 1.8
2062     /* Give the weapon to the golem now. A bit of a hack to check the
2063 root 1.79 * removed flag - it should only be set if weapon->split was
2064 root 1.8 * used above.
2065     */
2066 root 1.124 if (!weapon->flag [FLAG_REMOVED])
2067 root 1.16 weapon->remove ();
2068 root 1.46
2069 root 1.80 tmp->insert (weapon);
2070    
2071 root 1.8 /* To do everything necessary to let a golem use the weapon is a pain,
2072     * so instead, just set it as equipped (otherwise, we need to update
2073     * body_info, skills, etc)
2074     */
2075 root 1.124 tmp->set_flag (FLAG_USE_WEAPON);
2076     weapon->set_flag (FLAG_APPLIED);
2077 root 1.24 tmp->update_stats ();
2078 root 1.8
2079     /* There used to be 'odd' code that basically seemed to take the absolute
2080     * value of the weapon->magic an use that. IMO, that doesn't make sense -
2081     * if you're using a crappy weapon, it shouldn't be as good.
2082     */
2083    
2084     /* modify weapon's animated wc */
2085     tmp->stats.wc = tmp->stats.wc - SP_level_range_adjust (caster, spell) - 5 * weapon->stats.Dex - 2 * weapon->stats.Str - weapon->magic;
2086     if (tmp->stats.wc < -127)
2087     tmp->stats.wc = -127;
2088    
2089     /* Modify hit points for weapon */
2090     tmp->stats.maxhp = tmp->stats.maxhp + spell->duration +
2091     SP_level_duration_adjust (caster, spell) + +8 * weapon->magic + 12 * weapon->stats.Con;
2092     if (tmp->stats.maxhp < 0)
2093     tmp->stats.maxhp = 10;
2094     tmp->stats.hp = tmp->stats.maxhp;
2095    
2096     /* Modify weapon's damage */
2097     tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell) + weapon->stats.dam + weapon->magic + 5 * weapon->stats.Str;
2098     if (tmp->stats.dam < 0)
2099     tmp->stats.dam = 127;
2100    
2101    
2102     /* attacktype */
2103     if (!tmp->attacktype)
2104     tmp->attacktype = AT_PHYSICAL;
2105    
2106 root 1.114 for (i = 0; i < NROFATTACKS; i++)
2107     tmp->resist[i] = 50 - (op->material->save[i] * 5);
2108    
2109     a = op->material->save[0];
2110 root 1.63
2111 root 1.8 /* Set weapon's immunity */
2112     tmp->resist[ATNR_CONFUSION] = 100;
2113     tmp->resist[ATNR_POISON] = 100;
2114     tmp->resist[ATNR_SLOW] = 100;
2115     tmp->resist[ATNR_PARALYZE] = 100;
2116     tmp->resist[ATNR_TURN_UNDEAD] = 100;
2117     tmp->resist[ATNR_FEAR] = 100;
2118     tmp->resist[ATNR_DEPLETE] = 100;
2119     tmp->resist[ATNR_DEATH] = 100;
2120     tmp->resist[ATNR_BLIND] = 100;
2121    
2122     /* Improve weapon's armour value according to best save vs. physical of its material */
2123    
2124     if (a > 14)
2125     a = 14;
2126 root 1.63
2127 root 1.8 tmp->resist[ATNR_PHYSICAL] = 100 - (int) ((100.0 - (float) tmp->resist[ATNR_PHYSICAL]) / (30.0 - 2.0 * a));
2128    
2129     /* Determine golem's speed */
2130 root 1.26 tmp->set_speed (min (3.33, 0.4 + 0.1 * SP_level_range_adjust (caster, spell)));
2131 root 1.8
2132     if (!spell->race)
2133     {
2134     sprintf (buf, "animated %s", &weapon->name);
2135     tmp->name = buf;
2136    
2137     tmp->face = weapon->face;
2138     tmp->animation_id = weapon->animation_id;
2139     tmp->anim_speed = weapon->anim_speed;
2140     tmp->last_anim = weapon->last_anim;
2141     tmp->state = weapon->state;
2142 root 1.26 tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE];
2143 elmex 1.1 }
2144    
2145 root 1.8 /* make experience increase in proportion to the strength of the summoned creature. */
2146 root 1.113 tmp->stats.exp *= 1 + (max (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell));
2147 root 1.8
2148     tmp->speed_left = -1;
2149     tmp->direction = dir;
2150 root 1.27
2151     m->insert (tmp, x, y, op);
2152 root 1.8 return 1;
2153 elmex 1.1 }
2154    
2155     /* cast_daylight() - changes the map darkness level *lower* */
2156    
2157     /* cast_change_map_lightlevel: Was cast_daylight/nightfall.
2158     * This changes the light level for the entire map.
2159     */
2160 root 1.8 int
2161     cast_change_map_lightlevel (object *op, object *caster, object *spell)
2162     {
2163     int success;
2164 elmex 1.1
2165 root 1.8 if (!op->map)
2166     return 0; /* shouldnt happen */
2167 elmex 1.1
2168 root 1.28 success = op->map->change_map_light (spell->stats.dam);
2169    
2170 root 1.8 if (!success)
2171     {
2172     if (spell->stats.dam < 0)
2173 root 1.125 op->failmsg ("It can be no brighter here.");
2174 root 1.8 else
2175 root 1.125 op->failmsg ("It can be no darker here.");
2176 elmex 1.1 }
2177 root 1.92
2178 root 1.8 return success;
2179 elmex 1.1 }
2180    
2181     /* create an aura spell object and put it in the player's inventory.
2182     * as usual, op is player, caster is the object casting the spell,
2183     * spell is the spell object itself.
2184     */
2185 root 1.8 int
2186     create_aura (object *op, object *caster, object *spell)
2187 elmex 1.1 {
2188 root 1.8 int refresh = 0;
2189     object *new_aura;
2190 elmex 1.1
2191 root 1.8 new_aura = present_arch_in_ob (spell->other_arch, op);
2192     if (new_aura)
2193     refresh = 1;
2194     else
2195 root 1.116 new_aura = spell->other_arch->instance ();
2196 root 1.8
2197     new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell);
2198    
2199     new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
2200    
2201     set_spell_skill (op, caster, spell, new_aura);
2202     new_aura->attacktype = spell->attacktype;
2203    
2204 root 1.89 new_aura->level = casting_level (caster, spell);
2205 root 1.71
2206 root 1.8 if (refresh)
2207     new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
2208     else
2209     new_draw_info (NDI_UNIQUE, 0, op, "You create an aura of magical force.");
2210 root 1.71
2211 root 1.8 insert_ob_in_ob (new_aura, op);
2212 root 1.71 new_aura->set_owner (op);
2213    
2214 root 1.8 return 1;
2215 elmex 1.1 }
2216    
2217     /* move aura function. An aura is a part of someone's inventory,
2218     * which he carries with him, but which acts on the map immediately
2219     * around him.
2220     * Aura parameters:
2221     * duration: duration counter.
2222     * attacktype: aura's attacktype
2223     * other_arch: archetype to drop where we attack
2224     */
2225 root 1.8 void
2226     move_aura (object *aura)
2227     {
2228     /* auras belong in inventories */
2229 root 1.72 object *env = aura->env;
2230     object *owner = aura->owner;
2231 root 1.8
2232     /* no matter what we've gotta remove the aura...
2233     * we'll put it back if its time isn't up.
2234     */
2235 root 1.16 aura->remove ();
2236 root 1.8
2237     /* exit if we're out of gas */
2238     if (aura->duration-- < 0)
2239     {
2240 root 1.91 aura->destroy ();
2241 root 1.8 return;
2242     }
2243    
2244     /* auras only exist in inventories */
2245 root 1.72 if (!env || !env->map)
2246 root 1.8 {
2247 root 1.91 aura->destroy ();
2248 root 1.8 return;
2249     }
2250 root 1.17
2251 root 1.8 /* we need to jump out of the inventory for a bit
2252     * in order to hit the map conveniently.
2253     */
2254 root 1.27 aura->insert_at (env, aura);
2255 root 1.8
2256 root 1.72 for (int i = 1; i < 9; i++)
2257 root 1.8 {
2258 root 1.72 mapxy pos (env);
2259     pos.move (i);
2260 root 1.8
2261 root 1.72 /* Consider the movement type of the person with the aura as
2262     * movement type of the aura. Eg, if the player is flying, the aura
2263 root 1.8 * is flying also, if player is walking, it is on the ground, etc.
2264     */
2265 root 1.72 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block)))
2266 elmex 1.6 {
2267 root 1.8 hit_map (aura, i, aura->attacktype, 0);
2268 root 1.5
2269 root 1.8 if (aura->other_arch)
2270 root 1.116 pos.insert (aura->other_arch->instance (), aura);
2271 root 1.5 }
2272 elmex 1.1 }
2273 root 1.27
2274 root 1.8 /* put the aura back in the player's inventory */
2275 root 1.72 env->insert (aura);
2276     aura->set_owner (owner);
2277 elmex 1.1 }
2278    
2279     /* moves the peacemaker spell.
2280     * op is the piece object.
2281 root 1.8 */
2282     void
2283     move_peacemaker (object *op)
2284     {
2285 root 1.93 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above)
2286 root 1.8 {
2287     int atk_lev, def_lev;
2288 root 1.81 object *victim = tmp->head_ ();
2289 elmex 1.1
2290 root 1.124 if (!victim->flag [FLAG_MONSTER])
2291 root 1.8 continue;
2292 root 1.81
2293 root 1.124 if (victim->flag [FLAG_UNAGGRESSIVE])
2294 root 1.8 continue;
2295 root 1.81
2296 root 1.8 if (victim->stats.exp == 0)
2297     continue;
2298 elmex 1.1
2299 root 1.113 def_lev = max (1, victim->level);
2300     atk_lev = max (1, op->level);
2301 elmex 1.1
2302 root 1.8 if (rndm (0, atk_lev - 1) > def_lev)
2303     {
2304     /* make this sucker peaceful. */
2305 elmex 1.1
2306 root 1.81 INVOKE_OBJECT (KILL, victim, ARG_OBJECT (op));
2307 root 1.19 change_exp (op->owner, victim->stats.exp, op->skill, 0);
2308 root 1.8 victim->stats.exp = 0;
2309 elmex 1.1 #if 0
2310 root 1.8 /* No idea why these were all set to zero - if something
2311     * makes this creature agressive, he should still do damage.
2312     */
2313     victim->stats.dam = 0;
2314     victim->stats.sp = 0;
2315     victim->stats.grace = 0;
2316     victim->stats.Pow = 0;
2317 elmex 1.1 #endif
2318 root 1.8 victim->attack_movement = RANDO2;
2319 root 1.124 victim->set_flag (FLAG_UNAGGRESSIVE);
2320     victim->set_flag (FLAG_RUN_AWAY);
2321     victim->set_flag (FLAG_RANDOM_MOVE);
2322     victim->clr_flag (FLAG_MONSTER);
2323 root 1.81
2324 root 1.8 if (victim->name)
2325 root 1.81 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s no longer feels like fighting.", &victim->name);
2326 root 1.5 }
2327 elmex 1.1 }
2328 root 1.8 }
2329    
2330 elmex 1.1 /* This writes a rune that contains the appropriate message.
2331     * There really isn't any adjustments we make.
2332     */
2333 root 1.8 int
2334     write_mark (object *op, object *spell, const char *msg)
2335     {
2336     if (!msg || msg[0] == 0)
2337     {
2338 root 1.125 op->failmsg ("Write what?");
2339 root 1.8 return 0;
2340 elmex 1.1 }
2341    
2342 sf-marcmagus 1.109 if (!msg_is_safe (msg))
2343 root 1.8 {
2344 root 1.125 op->failmsg ("Trying to cheat are we? H<@-signs are not allowed in marking runes.>");
2345 sf-marcmagus 1.109 LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg);
2346 root 1.8 return 0;
2347 elmex 1.1 }
2348 root 1.97
2349 root 1.8 if (!spell->other_arch)
2350     return 0;
2351 root 1.9
2352 root 1.116 object *tmp = spell->other_arch->instance ();
2353 root 1.9
2354 root 1.8 tmp->race = op->name; /*Save the owner of the rune */
2355 root 1.97 tmp->msg = msg;
2356 root 1.27
2357     tmp->insert_at (op, op, INS_BELOW_ORIGINATOR);
2358 root 1.97
2359 root 1.8 return 1;
2360 elmex 1.1 }
2361 root 1.97