ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.130
Committed: Wed Apr 21 05:48:35 2010 UTC (14 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.129: +9 -4 lines
Log Message:
curse/magic identify

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     {
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.129 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
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.129 if (!tmp->flag [FLAG_IDENTIFIED] && !tmp->invisible && tmp->need_identify ())
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 root 1.126 for (last = 0, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above)
1558 root 1.98 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 root 1.126 detect = 0;
1569 root 1.98 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 root 1.127 || (tmp->type == SIGN && tmp->face != magicmouth_face)
1587 elmex 1.121 || 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 root 1.127 printf ("show inv %s\n", tmp->debug_desc());//D
1595 root 1.98 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4)
1596     {
1597     tmp->invisible = 0;
1598     done_one = 1;
1599     }
1600     }
1601    
1602 root 1.124 if (tmp->flag [FLAG_IS_FLOOR])
1603 root 1.98 floor = 1;
1604    
1605     /* All detections below this point don't descend beneath the floor,
1606     * so just continue on. We could be clever and look at the type of
1607     * detection to completely break out if we don't care about objects beneath
1608     * the floor, but once we get to the floor, not likely a very big issue anyways.
1609     */
1610     if (floor)
1611     continue;
1612    
1613     /* I had thought about making detect magic and detect curse
1614     * show the flash the magic item like it does for detect monster.
1615     * however, if the object is within sight, this would then make it
1616     * difficult to see what object is magical/cursed, so the
1617     * effect wouldn't be as apparent.
1618     */
1619    
1620     /* detect magic */
1621 root 1.130 if (spell->flag [FLAG_KNOWN_MAGICAL]
1622     && !tmp->flag [FLAG_KNOWN_MAGICAL]
1623     && !tmp->flag [FLAG_IDENTIFIED]
1624     && tmp->need_identify ()
1625     && is_magical (tmp))
1626 root 1.98 {
1627 root 1.124 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1628 elmex 1.121 /* make runes more visible */
1629 root 1.98 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC)
1630     tmp->stats.Cha /= 4;
1631    
1632     done_one = 1;
1633     }
1634    
1635     /* detect monster */
1636 root 1.124 if (spell->flag [FLAG_MONSTER] && (tmp->flag [FLAG_MONSTER] || tmp->type == PLAYER))
1637 root 1.98 {
1638     done_one = 2;
1639    
1640     if (!detect)
1641     detect = tmp;
1642     }
1643    
1644     /* Basically, if race is set in the spell, then the creatures race must
1645     * match that. if the spell race is set to GOD, then the gods opposing
1646     * race must match.
1647     */
1648 root 1.124 if (spell->race && tmp->flag [FLAG_MONSTER] && tmp->race &&
1649 root 1.98 ((spell->race == shstr_GOD && god && god->slaying.contains (tmp->race)) ||
1650     spell->race.contains (tmp->race)))
1651     {
1652     done_one = 2;
1653    
1654     if (!detect)
1655     detect = tmp;
1656     }
1657 root 1.21
1658 root 1.130 if (spell->flag [FLAG_KNOWN_CURSED]
1659     && !tmp->flag [FLAG_KNOWN_CURSED]
1660     && tmp->need_identify ()
1661     && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1662 root 1.98 {
1663 root 1.124 tmp->set_flag (FLAG_KNOWN_CURSED);
1664 root 1.98 done_one = 1;
1665     }
1666 elmex 1.121
1667     // Do mining detection spell:
1668     if (spell->last_sp == 1) // 1 - detect any vein
1669     {
1670     if (tmp->type == VEIN)
1671     {
1672     if (tmp->other_arch)
1673     {
1674     if (!detect)
1675     detect = tmp->other_arch;
1676     done_one = 2;
1677     }
1678     else
1679     done_one = 1;
1680     }
1681     }
1682 root 1.98 } /* for stack of objects on this space */
1683 elmex 1.1
1684 root 1.98 /* Code here puts an effect of the spell on the space, so you can see
1685     * where the magic is.
1686     */
1687     if (done_one)
1688     {
1689 root 1.116 object *detect_ob = spell->other_arch->instance ();
1690 root 1.8
1691 root 1.98 /* if this is set, we want to copy the face */
1692     if (done_one == 2 && detect)
1693     {
1694     detect_ob->face = detect->face;
1695     detect_ob->animation_id = detect->animation_id;
1696     detect_ob->anim_speed = detect->anim_speed;
1697     detect_ob->last_anim = 0;
1698     /* by default, the detect_ob is already animated */
1699 root 1.124 if (!detect->flag [FLAG_ANIMATE])
1700     detect_ob->clr_flag (FLAG_ANIMATE);
1701 root 1.98 }
1702 root 1.27
1703 elmex 1.121 m->insert (detect_ob, nx, ny, op, INS_ON_TOP);
1704 root 1.98 }
1705     } /* for processing the surrounding spaces */
1706 root 1.5
1707    
1708 root 1.8 /* Now process objects in the players inventory if detect curse or magic */
1709 root 1.124 if (spell->flag [FLAG_KNOWN_CURSED] || spell->flag [FLAG_KNOWN_MAGICAL])
1710 root 1.8 {
1711     done_one = 0;
1712 root 1.80
1713 root 1.8 for (tmp = op->inv; tmp; tmp = tmp->below)
1714     {
1715 root 1.124 if (!tmp->invisible && !tmp->flag [FLAG_IDENTIFIED])
1716 root 1.8 {
1717 root 1.124 if (spell->flag [FLAG_KNOWN_MAGICAL] && is_magical (tmp) && !tmp->flag [FLAG_KNOWN_MAGICAL])
1718 root 1.8 {
1719 root 1.124 tmp->set_flag (FLAG_KNOWN_MAGICAL);
1720 root 1.80
1721     if (object *pl = tmp->visible_to ())
1722     esrv_update_item (UPD_FLAGS, pl, tmp);
1723 root 1.5 }
1724 root 1.80
1725 root 1.124 if (spell->flag [FLAG_KNOWN_CURSED] && !tmp->flag [FLAG_KNOWN_CURSED] &&
1726     (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
1727 root 1.8 {
1728 root 1.124 tmp->set_flag (FLAG_KNOWN_CURSED);
1729 root 1.80
1730     if (object *pl = tmp->visible_to ())
1731     esrv_update_item (UPD_FLAGS, pl, tmp);
1732 root 1.5 }
1733 root 1.8 } /* if item is not identified */
1734     } /* for the players inventory */
1735     } /* if detect magic/curse and object is a player */
1736 root 1.80
1737 root 1.8 return 1;
1738 elmex 1.1 }
1739    
1740    
1741     /**
1742     * Checks if victim has overcharged mana. caster_level is the caster's (skill)
1743     * level whos spell did cause the overcharge.
1744     */
1745 root 1.8 static void
1746     charge_mana_effect (object *victim, int caster_level)
1747 elmex 1.1 {
1748    
1749 root 1.8 /* Prevent explosions for objects without mana. Without this check, doors
1750     * will explode, too.
1751     */
1752     if (victim->stats.maxsp <= 0)
1753     return;
1754 elmex 1.1
1755 root 1.8 new_draw_info (NDI_UNIQUE, 0, victim, "You feel energy course through you.");
1756 elmex 1.1
1757 root 1.8 if (victim->stats.sp >= victim->stats.maxsp * 2)
1758     {
1759     new_draw_info (NDI_UNIQUE, 0, victim, "Your head explodes!");
1760     victim->stats.sp = 2 * victim->stats.maxsp;
1761 elmex 1.99 create_exploding_ball_at (victim, caster_level);
1762 elmex 1.1 }
1763 root 1.8 else if (victim->stats.sp >= victim->stats.maxsp * 1.88)
1764 root 1.86 new_draw_info (NDI_UNIQUE | NDI_ORANGE, 0, victim, "You feel like your head is going to explode.");
1765 root 1.8 else if (victim->stats.sp >= victim->stats.maxsp * 1.66)
1766 root 1.27 new_draw_info (NDI_UNIQUE, 0, victim, "You get a splitting headache!");
1767 root 1.8 else if (victim->stats.sp >= victim->stats.maxsp * 1.5)
1768     {
1769     new_draw_info (NDI_UNIQUE, 0, victim, "Chaos fills your world.");
1770     confuse_player (victim, victim, 99);
1771 elmex 1.1 }
1772 root 1.8 else if (victim->stats.sp >= victim->stats.maxsp * 1.25)
1773 root 1.27 new_draw_info (NDI_UNIQUE, 0, victim, "You start hearing voices.");
1774 elmex 1.1 }
1775    
1776     /* cast_transfer
1777     * This spell transfers sp from the player to another person.
1778     * We let the target go above their normal maximum SP.
1779     */
1780    
1781 root 1.8 int
1782     cast_transfer (object *op, object *caster, object *spell, int dir)
1783     {
1784     object *plyr = NULL;
1785     sint16 x, y;
1786 root 1.13 maptile *m;
1787 root 1.8 int mflags;
1788    
1789     m = op->map;
1790     x = op->x + freearr_x[dir];
1791     y = op->y + freearr_y[dir];
1792    
1793     mflags = get_map_flags (m, &m, x, y, &x, &y);
1794    
1795     if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
1796     {
1797 root 1.22 for (plyr = GET_MAP_OB (m, x, y); plyr != NULL; plyr = plyr->above)
1798 root 1.124 if (plyr != op && plyr->flag [FLAG_ALIVE])
1799 root 1.8 break;
1800 elmex 1.1 }
1801    
1802    
1803 root 1.8 /* If we did not find a player in the specified direction, transfer
1804     * to anyone on top of us. This is used for the rune of transference mostly.
1805     */
1806     if (plyr == NULL)
1807 root 1.22 for (plyr = GET_MAP_OB (op->map, op->x, op->y); plyr != NULL; plyr = plyr->above)
1808 root 1.124 if (plyr != op && plyr->flag [FLAG_ALIVE])
1809 root 1.8 break;
1810 elmex 1.1
1811 root 1.8 if (!plyr)
1812     {
1813 root 1.125 op->failmsg ("There is no one there.");
1814 root 1.8 return 0;
1815 elmex 1.1 }
1816 root 1.8 /* give sp */
1817     if (spell->stats.dam > 0)
1818     {
1819     plyr->stats.sp += spell->stats.dam + SP_level_dam_adjust (caster, spell);
1820 root 1.89 charge_mana_effect (plyr, casting_level (caster, spell));
1821 root 1.8 return 1;
1822 elmex 1.1 }
1823 root 1.8 /* suck sp away. Can't suck sp from yourself */
1824     else if (op != plyr)
1825     {
1826     /* old dragin magic used floats. easier to just use ints and divide by 100 */
1827    
1828     int rate = -spell->stats.dam + SP_level_dam_adjust (caster, spell), sucked;
1829    
1830     if (rate > 95)
1831     rate = 95;
1832    
1833     sucked = (plyr->stats.sp * rate) / 100;
1834     plyr->stats.sp -= sucked;
1835 root 1.124 if (op->flag [FLAG_ALIVE])
1836 root 1.8 {
1837     /* Player doesn't get full credit */
1838     sucked = (sucked * rate) / 100;
1839     op->stats.sp += sucked;
1840     if (sucked > 0)
1841     {
1842 root 1.89 charge_mana_effect (op, casting_level (caster, spell));
1843 root 1.5 }
1844     }
1845 root 1.8 return 1;
1846 elmex 1.1 }
1847 root 1.8 return 0;
1848 elmex 1.1 }
1849    
1850    
1851     /* counterspell: nullifies spell effects.
1852     * op is the counterspell object, dir is the direction
1853     * it was cast in.
1854     * Basically, if the object has a magic attacktype,
1855     * this may nullify it.
1856     */
1857 root 1.8 void
1858     counterspell (object *op, int dir)
1859 elmex 1.1 {
1860 root 1.8 object *tmp, *head, *next;
1861     int mflags;
1862 root 1.13 maptile *m;
1863 root 1.8 sint16 sx, sy;
1864    
1865     sx = op->x + freearr_x[dir];
1866     sy = op->y + freearr_y[dir];
1867     m = op->map;
1868     mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1869     if (mflags & P_OUT_OF_MAP)
1870     return;
1871 elmex 1.1
1872 root 1.22 for (tmp = GET_MAP_OB (m, sx, sy); tmp != NULL; tmp = next)
1873 root 1.8 {
1874     next = tmp->above;
1875 elmex 1.1
1876 root 1.8 /* Need to look at the head object - otherwise, if tmp
1877     * points to a monster, we don't have all the necessary
1878     * info for it.
1879     */
1880     if (tmp->head)
1881     head = tmp->head;
1882     else
1883     head = tmp;
1884    
1885     /* don't attack our own spells */
1886     if (tmp->owner && tmp->owner == op->owner)
1887     continue;
1888    
1889     /* Basically, if the object is magical and not counterspell,
1890     * we will more or less remove the object. Don't counterspell
1891     * monsters either.
1892     */
1893 elmex 1.1
1894 elmex 1.44 if (head->attacktype & AT_MAGIC
1895     && !(head->attacktype & AT_COUNTERSPELL)
1896 root 1.124 && !head->flag [FLAG_MONSTER]
1897 elmex 1.44 && (op->level > head->level))
1898 root 1.91 head->destroy ();
1899 root 1.8 else
1900     switch (head->type)
1901     {
1902     case SPELL_EFFECT:
1903 elmex 1.44 // XXX: Don't affect floor spelleffects. See also XXX comment
1904     // about sanctuary in spell_util.C
1905 root 1.124 if (tmp->flag [FLAG_IS_FLOOR])
1906 elmex 1.44 continue;
1907    
1908 root 1.8 if (op->level > head->level)
1909 root 1.91 head->destroy ();
1910 root 1.17
1911 root 1.5 break;
1912    
1913 root 1.8 /* I really don't get this rune code that much - that
1914     * random chance seems really low.
1915     */
1916     case RUNE:
1917     if (rndm (0, 149) == 0)
1918     {
1919     head->stats.hp--; /* weaken the rune */
1920     if (!head->stats.hp)
1921 root 1.91 head->destroy ();
1922 root 1.8 }
1923 root 1.5 break;
1924 root 1.8 }
1925 elmex 1.1 }
1926     }
1927    
1928     /* cast_consecrate() - a spell to make an altar your god's */
1929 root 1.8 int
1930     cast_consecrate (object *op, object *caster, object *spell)
1931     {
1932     char buf[MAX_BUF];
1933 elmex 1.1
1934 root 1.8 object *tmp, *god = find_god (determine_god (op));
1935 elmex 1.1
1936 root 1.8 if (!god)
1937     {
1938 root 1.125 op->failmsg ("You can't consecrate anything if you don't worship a god!");
1939 root 1.8 return 0;
1940 elmex 1.1 }
1941 root 1.8
1942     for (tmp = op->below; tmp; tmp = tmp->below)
1943     {
1944 root 1.124 if (tmp->flag [FLAG_IS_FLOOR])
1945 root 1.8 break;
1946     if (tmp->type == HOLY_ALTAR)
1947     {
1948    
1949 root 1.89 if (tmp->level > casting_level (caster, spell))
1950 root 1.8 {
1951 root 1.125 op->failmsgf ("You are not powerful enough to reconsecrate the %s", &tmp->name);
1952 root 1.8 return 0;
1953     }
1954     else
1955     {
1956     /* If we got here, we are consecrating an altar */
1957     sprintf (buf, "Altar of %s", &god->name);
1958     tmp->name = buf;
1959 root 1.89 tmp->level = casting_level (caster, spell);
1960 root 1.8 tmp->other_arch = god->arch;
1961 root 1.80
1962 root 1.8 if (op->type == PLAYER)
1963     esrv_update_item (UPD_NAME, op, tmp);
1964 root 1.80
1965 root 1.8 new_draw_info_format (NDI_UNIQUE, 0, op, "You consecrated the altar to %s!", &god->name);
1966     return 1;
1967 root 1.5 }
1968     }
1969 elmex 1.1 }
1970 root 1.125
1971     op->failmsg ("You are not standing over an altar!");
1972 root 1.8 return 0;
1973 elmex 1.1 }
1974    
1975     /* animate_weapon -
1976     * Generalization of staff_to_snake. Makes a golem out of the caster's weapon.
1977     * The golem is based on the archetype specified, modified by the caster's level
1978     * and the attributes of the weapon. The weapon is inserted in the golem's
1979     * inventory so that it falls to the ground when the golem dies.
1980     * This code was very odd - code early on would only let players use the spell,
1981     * yet the code wass full of player checks. I've presumed that the code
1982     * that only let players use it was correct, and removed all the other
1983     * player checks. MSW 2003-01-06
1984     */
1985 root 1.8 int
1986     animate_weapon (object *op, object *caster, object *spell, int dir)
1987     {
1988     char buf[MAX_BUF];
1989     int a, i;
1990     sint16 x, y;
1991 root 1.13 maptile *m;
1992 root 1.8
1993     if (!spell->other_arch)
1994     {
1995     new_draw_info (NDI_UNIQUE, 0, op, "Oops, program error!");
1996     LOG (llevError, "animate_weapon failed: spell %s missing other_arch!\n", &spell->name);
1997     return 0;
1998 elmex 1.1 }
1999 root 1.8 /* exit if it's not a player using this spell. */
2000     if (op->type != PLAYER)
2001     return 0;
2002 elmex 1.1
2003 root 1.8 /* if player already has a golem, abort */
2004 root 1.49 if (object *golem = op->contr->golem)
2005 root 1.8 {
2006 root 1.46 control_golem (golem, dir);
2007 root 1.8 return 0;
2008 elmex 1.1 }
2009    
2010 root 1.8 /* if no direction specified, pick one */
2011     if (!dir)
2012 root 1.84 dir = find_free_spot (spell->other_arch, op->map, op->x, op->y, 1, 9);
2013 root 1.8
2014     m = op->map;
2015     x = op->x + freearr_x[dir];
2016     y = op->y + freearr_y[dir];
2017    
2018     /* if there's no place to put the golem, abort */
2019 root 1.84 if (dir < 0 || (get_map_flags (m, &m, x, y, &x, &y) & P_OUT_OF_MAP)
2020     || ((spell->other_arch->move_type & GET_MAP_MOVE_BLOCK (m, x, y)) == spell->other_arch->move_type))
2021 root 1.8 {
2022 root 1.125 op->failmsg ("There is something in the way.");
2023 root 1.8 return 0;
2024 elmex 1.1 }
2025    
2026 root 1.8 /* Use the weapon marked by the player. */
2027 root 1.128 object *weapon = op->mark ();
2028 elmex 1.1
2029 root 1.8 if (!weapon)
2030     {
2031 root 1.125 op->failmsg ("You must mark a weapon to use with this spell!");
2032 root 1.8 return 0;
2033     }
2034 root 1.93
2035     if (spell->race && weapon->arch->archname != spell->race)
2036 root 1.8 {
2037 root 1.125 op->failmsg ("The spell fails to transform your weapon.");
2038 root 1.8 return 0;
2039     }
2040 root 1.93
2041 root 1.8 if (weapon->type != WEAPON)
2042     {
2043 root 1.125 op->failmsg ("You need to wield a weapon to animate it.");
2044 root 1.8 return 0;
2045 elmex 1.1 }
2046 root 1.93
2047 root 1.124 if (weapon->flag [FLAG_APPLIED])
2048 root 1.8 {
2049 root 1.125 op->failmsgf ("You need to unequip %s before using it in this spell", query_name (weapon));
2050 root 1.8 return 0;
2051 elmex 1.1 }
2052 root 1.8
2053 root 1.80 weapon = weapon->split ();
2054 root 1.8
2055     /* create the golem object */
2056 root 1.128 object *tmp = spell->other_arch->instance ();
2057 root 1.8
2058     /* if animated by a player, give the player control of the golem */
2059 root 1.124 tmp->clr_flag (FLAG_MONSTER);
2060 root 1.8 tmp->stats.exp = 0;
2061     add_friendly_object (tmp);
2062     tmp->type = GOLEM;
2063 root 1.19 tmp->set_owner (op);
2064 root 1.49 op->contr->golem = tmp;
2065 root 1.46 set_spell_skill (op, caster, spell, tmp);
2066 root 1.8
2067     /* Give the weapon to the golem now. A bit of a hack to check the
2068 root 1.79 * removed flag - it should only be set if weapon->split was
2069 root 1.8 * used above.
2070     */
2071 root 1.124 if (!weapon->flag [FLAG_REMOVED])
2072 root 1.16 weapon->remove ();
2073 root 1.46
2074 root 1.80 tmp->insert (weapon);
2075    
2076 root 1.8 /* To do everything necessary to let a golem use the weapon is a pain,
2077     * so instead, just set it as equipped (otherwise, we need to update
2078     * body_info, skills, etc)
2079     */
2080 root 1.124 tmp->set_flag (FLAG_USE_WEAPON);
2081     weapon->set_flag (FLAG_APPLIED);
2082 root 1.24 tmp->update_stats ();
2083 root 1.8
2084     /* There used to be 'odd' code that basically seemed to take the absolute
2085     * value of the weapon->magic an use that. IMO, that doesn't make sense -
2086     * if you're using a crappy weapon, it shouldn't be as good.
2087     */
2088    
2089     /* modify weapon's animated wc */
2090     tmp->stats.wc = tmp->stats.wc - SP_level_range_adjust (caster, spell) - 5 * weapon->stats.Dex - 2 * weapon->stats.Str - weapon->magic;
2091     if (tmp->stats.wc < -127)
2092     tmp->stats.wc = -127;
2093    
2094     /* Modify hit points for weapon */
2095     tmp->stats.maxhp = tmp->stats.maxhp + spell->duration +
2096     SP_level_duration_adjust (caster, spell) + +8 * weapon->magic + 12 * weapon->stats.Con;
2097     if (tmp->stats.maxhp < 0)
2098     tmp->stats.maxhp = 10;
2099     tmp->stats.hp = tmp->stats.maxhp;
2100    
2101     /* Modify weapon's damage */
2102     tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell) + weapon->stats.dam + weapon->magic + 5 * weapon->stats.Str;
2103     if (tmp->stats.dam < 0)
2104     tmp->stats.dam = 127;
2105    
2106    
2107     /* attacktype */
2108     if (!tmp->attacktype)
2109     tmp->attacktype = AT_PHYSICAL;
2110    
2111 root 1.114 for (i = 0; i < NROFATTACKS; i++)
2112     tmp->resist[i] = 50 - (op->material->save[i] * 5);
2113    
2114     a = op->material->save[0];
2115 root 1.63
2116 root 1.8 /* Set weapon's immunity */
2117     tmp->resist[ATNR_CONFUSION] = 100;
2118     tmp->resist[ATNR_POISON] = 100;
2119     tmp->resist[ATNR_SLOW] = 100;
2120     tmp->resist[ATNR_PARALYZE] = 100;
2121     tmp->resist[ATNR_TURN_UNDEAD] = 100;
2122     tmp->resist[ATNR_FEAR] = 100;
2123     tmp->resist[ATNR_DEPLETE] = 100;
2124     tmp->resist[ATNR_DEATH] = 100;
2125     tmp->resist[ATNR_BLIND] = 100;
2126    
2127     /* Improve weapon's armour value according to best save vs. physical of its material */
2128    
2129     if (a > 14)
2130     a = 14;
2131 root 1.63
2132 root 1.8 tmp->resist[ATNR_PHYSICAL] = 100 - (int) ((100.0 - (float) tmp->resist[ATNR_PHYSICAL]) / (30.0 - 2.0 * a));
2133    
2134     /* Determine golem's speed */
2135 root 1.26 tmp->set_speed (min (3.33, 0.4 + 0.1 * SP_level_range_adjust (caster, spell)));
2136 root 1.8
2137     if (!spell->race)
2138     {
2139     sprintf (buf, "animated %s", &weapon->name);
2140     tmp->name = buf;
2141    
2142     tmp->face = weapon->face;
2143     tmp->animation_id = weapon->animation_id;
2144     tmp->anim_speed = weapon->anim_speed;
2145     tmp->last_anim = weapon->last_anim;
2146     tmp->state = weapon->state;
2147 root 1.26 tmp->flag [FLAG_ANIMATE] = weapon->flag [FLAG_ANIMATE];
2148 elmex 1.1 }
2149    
2150 root 1.8 /* make experience increase in proportion to the strength of the summoned creature. */
2151 root 1.113 tmp->stats.exp *= 1 + (max (spell->stats.maxgrace, spell->stats.sp) / casting_level (caster, spell));
2152 root 1.8
2153     tmp->speed_left = -1;
2154     tmp->direction = dir;
2155 root 1.27
2156     m->insert (tmp, x, y, op);
2157 root 1.8 return 1;
2158 elmex 1.1 }
2159    
2160     /* cast_daylight() - changes the map darkness level *lower* */
2161    
2162     /* cast_change_map_lightlevel: Was cast_daylight/nightfall.
2163     * This changes the light level for the entire map.
2164     */
2165 root 1.8 int
2166     cast_change_map_lightlevel (object *op, object *caster, object *spell)
2167     {
2168     int success;
2169 elmex 1.1
2170 root 1.8 if (!op->map)
2171     return 0; /* shouldnt happen */
2172 elmex 1.1
2173 root 1.28 success = op->map->change_map_light (spell->stats.dam);
2174    
2175 root 1.8 if (!success)
2176     {
2177     if (spell->stats.dam < 0)
2178 root 1.125 op->failmsg ("It can be no brighter here.");
2179 root 1.8 else
2180 root 1.125 op->failmsg ("It can be no darker here.");
2181 elmex 1.1 }
2182 root 1.92
2183 root 1.8 return success;
2184 elmex 1.1 }
2185    
2186     /* create an aura spell object and put it in the player's inventory.
2187     * as usual, op is player, caster is the object casting the spell,
2188     * spell is the spell object itself.
2189     */
2190 root 1.8 int
2191     create_aura (object *op, object *caster, object *spell)
2192 elmex 1.1 {
2193 root 1.8 int refresh = 0;
2194     object *new_aura;
2195 elmex 1.1
2196 root 1.8 new_aura = present_arch_in_ob (spell->other_arch, op);
2197     if (new_aura)
2198     refresh = 1;
2199     else
2200 root 1.116 new_aura = spell->other_arch->instance ();
2201 root 1.8
2202     new_aura->duration = spell->duration + 10 * SP_level_duration_adjust (caster, spell);
2203    
2204     new_aura->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
2205    
2206     set_spell_skill (op, caster, spell, new_aura);
2207     new_aura->attacktype = spell->attacktype;
2208    
2209 root 1.89 new_aura->level = casting_level (caster, spell);
2210 root 1.71
2211 root 1.8 if (refresh)
2212     new_draw_info (NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
2213     else
2214     new_draw_info (NDI_UNIQUE, 0, op, "You create an aura of magical force.");
2215 root 1.71
2216 root 1.8 insert_ob_in_ob (new_aura, op);
2217 root 1.71 new_aura->set_owner (op);
2218    
2219 root 1.8 return 1;
2220 elmex 1.1 }
2221    
2222     /* move aura function. An aura is a part of someone's inventory,
2223     * which he carries with him, but which acts on the map immediately
2224     * around him.
2225     * Aura parameters:
2226     * duration: duration counter.
2227     * attacktype: aura's attacktype
2228     * other_arch: archetype to drop where we attack
2229     */
2230 root 1.8 void
2231     move_aura (object *aura)
2232     {
2233     /* auras belong in inventories */
2234 root 1.72 object *env = aura->env;
2235     object *owner = aura->owner;
2236 root 1.8
2237     /* no matter what we've gotta remove the aura...
2238     * we'll put it back if its time isn't up.
2239     */
2240 root 1.16 aura->remove ();
2241 root 1.8
2242     /* exit if we're out of gas */
2243     if (aura->duration-- < 0)
2244     {
2245 root 1.91 aura->destroy ();
2246 root 1.8 return;
2247     }
2248    
2249     /* auras only exist in inventories */
2250 root 1.72 if (!env || !env->map)
2251 root 1.8 {
2252 root 1.91 aura->destroy ();
2253 root 1.8 return;
2254     }
2255 root 1.17
2256 root 1.8 /* we need to jump out of the inventory for a bit
2257     * in order to hit the map conveniently.
2258     */
2259 root 1.27 aura->insert_at (env, aura);
2260 root 1.8
2261 root 1.72 for (int i = 1; i < 9; i++)
2262 root 1.8 {
2263 root 1.72 mapxy pos (env);
2264     pos.move (i);
2265 root 1.8
2266 root 1.72 /* Consider the movement type of the person with the aura as
2267     * movement type of the aura. Eg, if the player is flying, the aura
2268 root 1.8 * is flying also, if player is walking, it is on the ground, etc.
2269     */
2270 root 1.72 if (pos.normalise () && !(OB_TYPE_MOVE_BLOCK (env, pos->move_block)))
2271 elmex 1.6 {
2272 root 1.8 hit_map (aura, i, aura->attacktype, 0);
2273 root 1.5
2274 root 1.8 if (aura->other_arch)
2275 root 1.116 pos.insert (aura->other_arch->instance (), aura);
2276 root 1.5 }
2277 elmex 1.1 }
2278 root 1.27
2279 root 1.8 /* put the aura back in the player's inventory */
2280 root 1.72 env->insert (aura);
2281     aura->set_owner (owner);
2282 elmex 1.1 }
2283    
2284     /* moves the peacemaker spell.
2285     * op is the piece object.
2286 root 1.8 */
2287     void
2288     move_peacemaker (object *op)
2289     {
2290 root 1.93 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above)
2291 root 1.8 {
2292     int atk_lev, def_lev;
2293 root 1.81 object *victim = tmp->head_ ();
2294 elmex 1.1
2295 root 1.124 if (!victim->flag [FLAG_MONSTER])
2296 root 1.8 continue;
2297 root 1.81
2298 root 1.124 if (victim->flag [FLAG_UNAGGRESSIVE])
2299 root 1.8 continue;
2300 root 1.81
2301 root 1.8 if (victim->stats.exp == 0)
2302     continue;
2303 elmex 1.1
2304 root 1.113 def_lev = max (1, victim->level);
2305     atk_lev = max (1, op->level);
2306 elmex 1.1
2307 root 1.8 if (rndm (0, atk_lev - 1) > def_lev)
2308     {
2309     /* make this sucker peaceful. */
2310 elmex 1.1
2311 root 1.81 INVOKE_OBJECT (KILL, victim, ARG_OBJECT (op));
2312 root 1.19 change_exp (op->owner, victim->stats.exp, op->skill, 0);
2313 root 1.8 victim->stats.exp = 0;
2314 elmex 1.1 #if 0
2315 root 1.8 /* No idea why these were all set to zero - if something
2316     * makes this creature agressive, he should still do damage.
2317     */
2318     victim->stats.dam = 0;
2319     victim->stats.sp = 0;
2320     victim->stats.grace = 0;
2321     victim->stats.Pow = 0;
2322 elmex 1.1 #endif
2323 root 1.8 victim->attack_movement = RANDO2;
2324 root 1.124 victim->set_flag (FLAG_UNAGGRESSIVE);
2325     victim->set_flag (FLAG_RUN_AWAY);
2326     victim->set_flag (FLAG_RANDOM_MOVE);
2327     victim->clr_flag (FLAG_MONSTER);
2328 root 1.81
2329 root 1.8 if (victim->name)
2330 root 1.81 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s no longer feels like fighting.", &victim->name);
2331 root 1.5 }
2332 elmex 1.1 }
2333 root 1.8 }
2334    
2335 elmex 1.1 /* This writes a rune that contains the appropriate message.
2336     * There really isn't any adjustments we make.
2337     */
2338 root 1.8 int
2339     write_mark (object *op, object *spell, const char *msg)
2340     {
2341     if (!msg || msg[0] == 0)
2342     {
2343 root 1.125 op->failmsg ("Write what?");
2344 root 1.8 return 0;
2345 elmex 1.1 }
2346    
2347 sf-marcmagus 1.109 if (!msg_is_safe (msg))
2348 root 1.8 {
2349 root 1.125 op->failmsg ("Trying to cheat are we? H<@-signs are not allowed in marking runes.>");
2350 sf-marcmagus 1.109 LOG (llevInfo, "write_mark: player %s tried to write bogus rune %s\n", &op->name, msg);
2351 root 1.8 return 0;
2352 elmex 1.1 }
2353 root 1.97
2354 root 1.8 if (!spell->other_arch)
2355     return 0;
2356 root 1.9
2357 root 1.116 object *tmp = spell->other_arch->instance ();
2358 root 1.9
2359 root 1.8 tmp->race = op->name; /*Save the owner of the rune */
2360 root 1.97 tmp->msg = msg;
2361 root 1.27
2362     tmp->insert_at (op, op, INS_BELOW_ORIGINATOR);
2363 root 1.97
2364 root 1.8 return 1;
2365 elmex 1.1 }
2366 root 1.97