ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.136
Committed: Mon Aug 23 16:26:31 2010 UTC (13 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.135: +4 -6 lines
Log Message:
use last_sp, not cursed/damned flags for remove_curse/damnation spells

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