ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.104
Committed: Sat Jun 27 03:51:05 2009 UTC (14 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_80, rel-2_79
Changes since 1.103: +22 -23 lines
Log Message:
dimdoor spellarg

File Contents

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