ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.77
Committed: Thu Nov 8 19:43:28 2007 UTC (16 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_4, rel-2_32
Changes since 1.76: +4 -4 lines
Log Message:
update copyrights and other minor stuff to deliantra

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