ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.121
Committed: Mon Mar 29 17:30:46 2010 UTC (14 years, 2 months ago) by elmex
Content type: text/plain
Branch: MAIN
Changes since 1.120: +38 -22 lines
Log Message:
added detect mineral spell.

File Contents

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