ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.103
Committed: Mon Jun 8 08:57:34 2009 UTC (14 years, 11 months ago) by elmex
Content type: text/plain
Branch: MAIN
Changes since 1.102: +18 -8 lines
Log Message:
fixed show invisible, to show objects of type CONTAINER.

(lets hope this doesn't break any quest too hard, but for tuk5 it
seems to be the only way to make the box visible...)

File Contents

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