ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.78
Committed: Tue Jan 15 12:02:24 2008 UTC (16 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_5, rel-2_43, rel-2_42, rel-2_41
Changes since 1.77: +0 -1 lines
Log Message:
*** empty log message ***

File Contents

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