ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.99
Committed: Tue Jan 13 13:29:57 2009 UTC (15 years, 4 months ago) by elmex
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_76, rel-2_77, rel-2_78
Changes since 1.98: +1 -9 lines
Log Message:
added cursed effect to lamps and torches.

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