ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_effect.C
Revision: 1.110
Committed: Mon Oct 12 14:00:59 2009 UTC (14 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_81
Changes since 1.109: +7 -6 lines
Log Message:
clarify license

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