ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.135
Committed: Fri Jul 2 19:58:19 2010 UTC (13 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.134: +1 -1 lines
Log Message:
*** empty log message ***

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