Crossfire Server, Trunk  R22010
spell_effect.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #define _GNU_SOURCE // strcasestr() is a GNU extension in string.h
20 
21 #include "global.h"
22 
23 #include <assert.h>
24 #include <ctype.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "living.h"
29 #include "object.h"
30 #include "shop.h"
31 #include "sounds.h"
32 #include "spells.h"
33 #include "sproto.h"
34 #include "assets.h"
35 
46 void cast_magic_storm(object *op, object *tmp, int lvl) {
47  if (!tmp)
48  return; /* error */
49  tmp->level = op->level;
50  tmp->range += lvl/5; /* increase the area of destruction */
51  tmp->duration += lvl/5;
52 
53  /* Put a cap on duration for this - if the player fails in their
54  * apartment, don't want it to go on so long that it kills them
55  * multiple times. Also, damage already increases with level,
56  * so don't really need to increase the duration as much either.
57  */
58  if (tmp->duration >= 40)
59  tmp->duration = 40;
60  tmp->stats.dam = lvl; /* nasty recoils! */
61  tmp->stats.maxhp = tmp->count; /* tract single parent */
62  if (tmp->stats.maxhp == 0)
63  tmp->stats.maxhp = 1;
64  object_insert_in_map_at(tmp, op->map, op, 0, op->x, op->y);
65 }
66 
81 int recharge(object *op, object *caster, object *spell_ob) {
82  object *wand, *tmp;
83  int ncharges;
84  char name[MAX_BUF];
85 
86  wand = find_marked_object(op);
87  if (wand == NULL || wand->type != WAND) {
89  "You need to mark the wand you want to recharge.");
90  return 0;
91  }
92  if (!(random_roll(0, 3, op, PREFER_HIGH))) {
93  query_name(wand, name, MAX_BUF);
95  "The %s vibrates violently, then explodes!",
96  name);
97  play_sound_map(SOUND_TYPE_ITEM, wand, 0, "explode");
98  object_remove(wand);
99  object_free(wand, 0);
100  tmp = create_archetype("fireball");
101  tmp->stats.dam = (spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob))/10;
102  if (!tmp->stats.dam)
103  tmp->stats.dam = 1;
104  tmp->stats.hp = tmp->stats.dam/2;
105  if (tmp->stats.hp < 2)
106  tmp->stats.hp = 2;
107  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
108  return 1;
109  }
110 
111  ncharges = (spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob));
112  if (wand->inv && wand->inv->level)
113  ncharges /= wand->inv->level;
114  else {
115  query_name(wand, name, MAX_BUF);
117  "Your %s is broken.",
118  name);
119  return 0;
120  }
121  if (!ncharges)
122  ncharges = 1;
123 
124  wand->stats.food += ncharges;
125  query_name(wand, name, MAX_BUF);
127  "The %s glows with power.",
128  name);
129 
130  if (wand->arch && QUERY_FLAG(&wand->arch->clone, FLAG_ANIMATE)) {
131  SET_FLAG(wand, FLAG_ANIMATE);
132  wand->speed = wand->arch->clone.speed;
133  object_update_speed(wand);
134  }
135  return 1;
136 }
137 
138 /******************************************************************************
139  * Start of polymorph related functions.
140  *
141  * Changed around for 0.94.3 - it will now look through and use all the
142  * possible choices for objects/monsters (before it was the first 80 -
143  * arbitrary hardcoded limit in this file.) Doing this will be a bit
144  * slower however - while before, it traversed the archetypes once and
145  * stored them into an array, it will now potentially traverse it
146  * an average of 1.5 times. This is probably more costly on the polymorph
147  * item function, since it is possible a couple lookups might be needed before
148  * an item of proper value is generated.
149  */
150 
159 static void polymorph_living(object *op, int level) {
160  archetype *at;
161  int x = op->x, y = op->y, numat = 0, choice, friendly;
162  mapstruct *map = op->map;
163  object *owner;
164 
165  op = HEAD(op);
166 
167  /* High level creatures are immune, as are creatures immune to magic. Otherwise,
168  * give the creature a saving throw.
169  */
170  if (op->level >= level*2
171  || did_make_save(op, op->level, op->resist[ATNR_MAGIC]/10)
172  || (op->resist[ATNR_MAGIC] == 100))
173  return;
174 
175  object_remove(op);
176 
177  /* First, count up the number of legal matches */
178  for (at = get_next_archetype(NULL); at != NULL; at = get_next_archetype(at))
179  if ((QUERY_FLAG((&at->clone), FLAG_MONSTER) == QUERY_FLAG(op, FLAG_MONSTER))
180  && (object_find_free_spot(&at->clone, map, x, y, 0, SIZEOFFREE) != -1)) {
181  numat++;
182  }
183 
184  if (!numat) {
185  object_insert_in_map_at(op, map, NULL, 0, x, y);
186  return; /* no valid matches? if so, return */
187  }
188 
189  /* Next make a choice, and loop through until we get to it */
190  choice = rndm(0, numat-1);
191  for (at = get_next_archetype(NULL); at != NULL; at = get_next_archetype(at))
192  if ((QUERY_FLAG((&at->clone), FLAG_MONSTER) == QUERY_FLAG(op, FLAG_MONSTER)) && (object_find_free_spot(&at->clone, map, x, y, 0, SIZEOFFREE) != -1)) {
193  if (!choice)
194  break;
195  else
196  choice--;
197  }
198 
199  /* Look through the monster. Unapply anything they have applied,
200  * and remove any spells. Note that if this is extended
201  * to players, that would need to get fixed somehow.
202  */
203  FOR_INV_PREPARE(op, tmp) {
204  if (QUERY_FLAG(tmp, FLAG_APPLIED))
205  apply_manual(op, tmp, 0);
206  if (tmp->type == SPELL) {
207  object_remove(tmp);
208  object_free(tmp, 0);
209  }
210  } FOR_INV_FINISH();
211 
212  /* Preserve some values for the new object */
213  owner = object_get_owner(op);
214  friendly = QUERY_FLAG(op, FLAG_FRIENDLY);
215  if (friendly)
217 
218  object_copy(&(at->clone), op);
219  if (owner != NULL)
220  object_set_owner(op, owner);
221  if (friendly) {
222  SET_FLAG(op, FLAG_FRIENDLY);
223  op->attack_movement = PETMOVE;
225  } else
227 
228  /* Put the new creature on the map */
229  if ((op = object_insert_in_map_at(op, map, owner, 0, x, y)) == NULL)
230  return;
231 
232  if (HAS_RANDOM_ITEMS(op))
233  create_treasure(op->randomitems, op, GT_INVISIBLE, map->difficulty, 0);
234 
235  /* Apply any objects. */
237 }
238 
239 
251 static void polymorph_melt(object *who, object *op) {
252  /* Not unique */
253  char name[MAX_BUF];
254 
255  query_name(op, name, MAX_BUF);
256  if (op->nrof > 1)
258  "The %s glow red, melt and evaporate!",
259  name);
260  else
262  "The %s glows red, melts and evaporates!",
263  name);
264  play_sound_map(SOUND_TYPE_ITEM, op, 0, "evaporate");
265  object_remove(op);
266  object_free(op, 0);
267  return;
268 }
269 
279 static void polymorph_item(object *who, object *op, int level) {
280  archetype *at;
281  int max_value, difficulty, tries = 0, choice, charges = op->stats.food, numat = 0;
282  object *new_ob;
283  mapstruct *m;
284  int16_t x, y;
285 
286  /* We try and limit the maximum value of the changed object. */
287  max_value = op->value*2;
288  if (max_value > 2000*(level/10))
289  max_value = 2000*(level/10)+(max_value-2000*(level/10))/3;
290 
291  /* Look through and try to find matching items. Can't turn into something
292  * invisible. Also, if the value is too high now, it would almost
293  * certainly be too high below.
294  */
295  for (at = get_next_archetype(NULL); at != NULL; at = get_next_archetype(at)) {
296  if (at->clone.type == op->type
297  && !at->clone.invisible
298  && at->clone.value > 0
299  && at->clone.value < max_value
300  && !QUERY_FLAG(&at->clone, FLAG_NO_DROP)
301  && !QUERY_FLAG(&at->clone, FLAG_STARTEQUIP))
302  numat++;
303  }
304 
305  if (!numat)
306  return;
307 
308  difficulty = op->magic*5;
309  if (difficulty < 0)
310  difficulty = 0;
311  new_ob = object_new();
312  do {
313  choice = rndm(0, numat-1);
314  for (at = get_next_archetype(NULL); at != NULL; at = get_next_archetype(at)) {
315  if (at->clone.type == op->type
316  && !at->clone.invisible
317  && at->clone.value > 0
318  && at->clone.value < max_value
319  && !QUERY_FLAG(&at->clone, FLAG_NO_DROP)
320  && !QUERY_FLAG(&at->clone, FLAG_STARTEQUIP)) {
321  if (!choice)
322  break;
323  else
324  choice--;
325  }
326  }
327 
328  object_copy(&(at->clone), new_ob);
329  fix_generated_item(new_ob, op, difficulty, FABS(op->magic), GT_ENVIRONMENT);
330  ++tries;
331  } while (new_ob->value > max_value && tries < 10);
332  if (new_ob->invisible) {
333  LOG(llevError, "polymorph_item: fix_generated_object made %s invisible?!\n", new_ob->name);
334  object_free(new_ob, FREE_OBJ_NO_DESTROY_CALLBACK);
335  return;
336  }
337 
338  /* Unable to generate an acceptable item? Melt it */
339  if (tries == 10) {
340  polymorph_melt(who, op);
341  object_free(new_ob, FREE_OBJ_NO_DESTROY_CALLBACK);
342  return;
343  }
344 
345  if (op->nrof && new_ob->nrof) {
346  new_ob->nrof = op->nrof;
347  /* decrease the number of items */
348  if (new_ob->nrof > 2)
349  new_ob->nrof -= rndm(0, op->nrof/2-1);
350  }
351 
352  /* We don't want rings to keep sustenance/hungry status. There are probably
353  * other cases too that should be checked.
354  */
355  if (charges && op->type != RING && op->type != FOOD)
356  op->stats.food = charges;
357 
358  x = op->x;
359  y = op->y;
360  m = op->map;
361  object_remove(op);
362  object_free(op, FREE_OBJ_NO_DESTROY_CALLBACK);
363  /*
364  * Don't want objects merged or re-arranged, as it then messes up the
365  * order
366  */
367  object_insert_in_map_at(new_ob, m, new_ob, INS_NO_MERGE|INS_NO_WALK_ON, x, y);
368 }
369 
380 void polymorph(object *op, object *who, int level) {
381  int tmp;
382 
383  /* Can't polymorph players right now */
384  /* polymorphing generators opens up all sorts of abuses */
385  if (op->type == PLAYER || QUERY_FLAG(op, FLAG_GENERATOR))
386  return;
387 
388  if (QUERY_FLAG(op, FLAG_MONSTER)) {
389  polymorph_living(op, level);
390  return;
391  }
392  /* If it is a living object of some other type, don't handle
393  * it now.
394  */
395  if (QUERY_FLAG(op, FLAG_ALIVE))
396  return;
397 
398  /* Don't want to morph flying arrows, etc... */
399  if (FABS(op->speed) > 0.001 && !QUERY_FLAG(op, FLAG_ANIMATE))
400  return;
401 
402  /* Do some sanity checking here. type=0 is unknown, objects
403  * without archetypes are not good. As are a few other
404  * cases.
405  */
406  if (op->type == 0
407  || op->arch == NULL
408  || QUERY_FLAG(op, FLAG_NO_PICK)
409  || op->move_block
410  || op->type == TREASURE)
411  return;
412 
413  tmp = rndm(0, 7);
414  if (tmp)
415  polymorph_item(who, op, level);
416  else
417  polymorph_melt(who, op);
418 }
419 
420 
434 int cast_polymorph(object *op, object *caster, object *spell_ob, int dir) {
435  object *tmp;
436  int range, mflags, maxrange, level;
437  mapstruct *m;
438 
439  if (dir == 0)
440  return 0;
441 
442  maxrange = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
443  level = caster_level(caster, spell_ob);
444  for (range = 1; range < maxrange; range++) {
445  int16_t x = op->x+freearr_x[dir]*range, y = op->y+freearr_y[dir]*range;
446  object *image;
447 
448  m = op->map;
449  mflags = get_map_flags(m, &m, x, y, &x, &y);
450 
451  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
452  break;
453 
454  if (GET_MAP_MOVE_BLOCK(m, x, y)&MOVE_FLY_LOW)
455  break;
456 
457  /* Get the top most object */
458  for (tmp = GET_MAP_OB(m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above)
459  ;
460 
461  /* Now start polymorphing the objects, top down */
463  /* Once we find the floor, no need to go further */
464  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
465  break;
466  polymorph(tmp, op, level);
468  image = arch_to_object(spell_ob->other_arch);
469  image->stats.food = 5;
470  image->speed_left = 0.1;
471  object_insert_in_map_at(image, m, op, 0, x, y);
472  }
473  return 1;
474 }
475 
502 int cast_create_missile(object *op, object *caster, object *spell, int dir, const char *stringarg) {
503  int missile_plus = 0, bonus_plus = 0;
504  const char *missile_name;
505  object *tmp, *missile;
506  tag_t tag;
507 
508  tmp = object_find_by_type_applied(op, BOW);
509  missile_name = tmp != NULL ? tmp->race : "arrow";
510 
511  missile_plus = spell->stats.dam+SP_level_dam_adjust(caster, spell);
512 
513  if (!strcmp(missile_name, "arrows"))
514  missile_name = "arrow";
515  else if (!strcmp(missile_name, "crossbow bolts"))
516  missile_name = "bolt";
517 
518  /* Check if the type (bolt/arrow) was specified with the spell */
519  if ( stringarg && strncmp(stringarg,"of ",3)==0 ) stringarg +=3;
520  if ( stringarg && strncmp(stringarg,"bolt",4)==0 ) {
521  missile_name = "bolt";
522  stringarg += 4;
523  while ( isalpha(*stringarg) ) ++stringarg;
524  while ( *stringarg==' ' ) ++stringarg;
525  }
526  if ( stringarg && strncmp(stringarg,"arrow",5)==0 ) {
527  missile_name = "arrow";
528  stringarg += 5;
529  while ( isalpha(*stringarg) ) ++stringarg;
530  while ( *stringarg==' ' ) ++stringarg;
531  }
532 
533  if (try_find_archetype(missile_name) == NULL) {
534  LOG(llevDebug, "Cast create_missile: could not find archetype %s\n", missile_name);
535  return 0;
536  }
537  missile = create_archetype(missile_name);
538 
539  if ( stringarg && strncmp(stringarg,"of ",3)==0 ) stringarg +=3;
540  if (stringarg) {
541  /* If it starts with a letter, presume it is a description */
542  if (isalpha(*stringarg)) {
543  artifact *al = find_artifactlist(missile->type)->items;
544 
545  for (; al != NULL; al = al->next)
546  if (!strcasecmp(al->item->name, stringarg))
547  break;
548 
549  if (!al) {
550  object_free(missile, FREE_OBJ_NO_DESTROY_CALLBACK);
552  "No such object %ss of %s",
553  missile_name, stringarg);
554  return 0;
555  }
556  if (al->item->slaying) {
557  object_free(missile, FREE_OBJ_NO_DESTROY_CALLBACK);
559  "You are not allowed to create %ss of %s",
560  missile_name, stringarg);
561  return 0;
562  }
563  give_artifact_abilities(missile, al->item);
564  /* These special arrows cost something extra. Don't have them also be
565  * magical - otherwise, in most cases, not enough will be created.
566  * I don't want to get into the parsing both plus and type.
567  */
568  bonus_plus = 1+(al->item->value/5);
569  missile_plus = 0;
570  } else if (atoi(stringarg) < missile_plus)
571  missile_plus = atoi(stringarg);
572  }
573  if (missile_plus > 4)
574  missile_plus = 4;
575  else if (missile_plus < -4)
576  missile_plus = -4;
577 
578  missile->nrof = spell->duration+SP_level_duration_adjust(caster, spell);
579  if (missile->nrof <= (uint32_t)3 * (missile_plus + bonus_plus)) {
580  object_free(missile, FREE_OBJ_NO_DESTROY_CALLBACK);
582  "This item is too powerful for you to create!");
583  return 0;
584  }
585  missile->nrof -= 3*(missile_plus+bonus_plus);
586  if (missile->nrof < 1)
587  missile->nrof = 1;
588 
589  missile->magic = missile_plus;
590  /* Can't get any money for these objects */
591  missile->value = 0;
592 
593  SET_FLAG(missile, FLAG_IDENTIFIED);
594  tag = missile->count;
595 
596  if (!cast_create_obj(op, missile, dir)
597  && op->type == PLAYER
598  && !object_was_destroyed(missile, tag)) {
599  pick_up(op, missile);
600  }
601  return 1;
602 }
603 
605 static archetype *food_choice;
606 static int food_value_choice;
607 static void food_each(archetype *arch) {
608  if (arch->clone.type == FOOD || arch->clone.type == DRINK) {
609  /* Basically, if the food value is something that is creatable
610  * under the limits of the spell and it is higher than
611  * the item we have now, take it instead.
612  */
613  if (arch->clone.stats.food <= food_value_choice
614  && (!food_choice || arch->clone.stats.food > food_choice->clone.stats.food))
615  food_choice = arch;
616  }
617 }
618 
639 int cast_create_food(object *op, object *caster, object *spell_ob, int dir, const char *stringarg) {
640  int food_value;
641  archetype *at = NULL;
642  object *new_op;
643 
644  food_value = spell_ob->stats.food+50*SP_level_duration_adjust(caster, spell_ob);
645 
646  if (stringarg) {
647  at = find_archetype_by_object_type_name(FOOD, stringarg);
648  if (at == NULL)
649  at = find_archetype_by_object_type_name(DRINK, stringarg);
650  if (at == NULL || at->clone.stats.food > food_value)
651  stringarg = NULL;
652  }
653 
654  if (!stringarg) {
655  /* We try to find the archetype with the maximum food value.
656  * This removes the dependency of hard coded food values in this
657  * function, and addition of new food types is automatically added.
658  * We don't use flesh types because the weight values of those need
659  * to be altered from the donor.
660  */
661 
662  food_choice = at;
663  food_value_choice = food_value;
665  at = food_choice;
666  }
667  /* Pretty unlikely (there are some very low food items), but you never
668  * know
669  */
670  if (!at) {
672  "You don't have enough experience to create any food.");
673  return 0;
674  }
675 
676  food_value /= at->clone.stats.food;
677  new_op = object_new();
678  object_copy(&at->clone, new_op);
679  new_op->nrof = food_value;
680 
681  new_op->value = 0;
682  if (new_op->nrof < 1)
683  new_op->nrof = 1;
684 
685  cast_create_obj(op, new_op, dir);
686  return 1;
687 }
688 
707 int probe(object *op, object *caster, object *spell_ob, int dir, int level) {
708  int r, mflags, maxrange;
709  mapstruct *m;
710 
711  if (!dir) {
712  examine_monster(op, op, level);
713  return 1;
714  }
715  maxrange = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
716  for (r = 1; r < maxrange; r++) {
717  int16_t x = op->x+r*freearr_x[dir], y = op->y+r*freearr_y[dir];
718 
719  m = op->map;
720  mflags = get_map_flags(m, &m, x, y, &x, &y);
721 
722  if (mflags&P_OUT_OF_MAP)
723  break;
724 
725  if (!QUERY_FLAG(op, FLAG_WIZCAST) && (mflags&P_NO_MAGIC)) {
727  "Something blocks your magic.");
728  return 0;
729  }
730  if (mflags&P_IS_ALIVE) {
731  FOR_MAP_PREPARE(m, x, y, tmp)
732  if (CAN_PROBE(tmp)) {
734  "You detect something.");
735  examine_monster(op, HEAD(tmp), level);
736  return 1;
737  }
738  FOR_MAP_FINISH();
739  }
740  }
742  "You detect nothing.");
743  return 1;
744 }
745 
746 
764 int makes_invisible_to(object *pl, object *mon) {
765  if (!pl->invisible)
766  return 0;
767  if (pl->type == PLAYER) {
768  /* If race isn't set, then invisible unless it is undead */
769  if (!pl->contr->invis_race) {
770  if (QUERY_FLAG(mon, FLAG_UNDEAD))
771  return 0;
772  return 1;
773  }
774  /* invis_race is set if we get here */
775  if (!strcmp(pl->contr->invis_race, "undead") && is_true_undead(mon))
776  return 1;
777  /* No race, can't be invisible to it */
778  if (!mon->race)
779  return 0;
780  if (strstr(mon->race, pl->contr->invis_race))
781  return 1;
782  /* Nothing matched above, return 0 */
783  return 0;
784  } else {
785  /* monsters are invisible to everything */
786  return 1;
787  }
788 }
789 
811 int cast_invisible(object *op, object *caster, object *spell_ob) {
812  object *tmp;
813 
814  if (op->invisible > 1000) {
816  "You can not extend the duration of your invisibility any further");
817  return 0;
818  }
819 
820  /* Remove the switch with 90% duplicate code - just handle the differences with
821  * and if statement or two.
822  */
823  op->invisible += spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
824  /* max duration */
825  if (op->invisible > 1000)
826  op->invisible = 1000;
827 
828  if (op->type == PLAYER) {
829  if (op->contr->invis_race)
830  FREE_AND_CLEAR_STR(op->contr->invis_race);
831  if (spell_ob->race)
832  op->contr->invis_race = add_refcount(spell_ob->race);
833  if (QUERY_FLAG(spell_ob, FLAG_MAKE_INVIS))
834  op->contr->tmp_invis = 0;
835  else
836  op->contr->tmp_invis = 1;
837 
838  op->contr->hidden = 0;
839  }
840  if (makes_invisible_to(op, op))
842  "You can't see your hands!");
843  else
845  "You feel more transparent!");
846 
847  object_update(op, UP_OBJ_FACE);
848 
849  /* Only search the active objects - only these should actually do
850  * harm to the player.
851  */
852  for (tmp = active_objects; tmp != NULL; tmp = tmp->active_next)
853  if (tmp->enemy == op)
854  object_set_enemy(tmp, NULL);
855  return 1;
856 }
857 
872 int cast_earth_to_dust(object *op, object *caster, object *spell_ob) {
873  int range, i, j, mflags;
874  int16_t sx, sy;
875  mapstruct *m;
876 
877  if (op->type != PLAYER)
878  return 0;
879 
880  range = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
881 
882  for (i = -range; i < range; i++)
883  for (j = -range; j < range; j++) {
884  sx = op->x+i;
885  sy = op->y+j;
886  m = op->map;
887  mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
888 
889  if (mflags&P_OUT_OF_MAP)
890  continue;
891 
892  /* If the space doesn't block, no wall here to remove
893  * Don't care too much what it blocks - this allows for
894  * any sort of earthwall/airwall/waterwall, etc
895  * type effects.
896  */
897  if (GET_MAP_MOVE_BLOCK(m, sx, sy)) {
898  FOR_MAP_PREPARE(m, sx, sy, tmp)
899  if (tmp && QUERY_FLAG(tmp, FLAG_TEAR_DOWN))
900  hit_player(tmp, 9998, op, AT_PHYSICAL, 0);
901  FOR_MAP_FINISH();
902  }
903  }
904  return 1;
905 }
906 
923 int cast_word_of_recall(object *op, object *caster, object *spell_ob) {
924  object *dummy;
925  int time;
926 
927  if (op->type != PLAYER)
928  return 0;
929 
930  if (object_find_by_type_subtype(op, SPELL_EFFECT, SP_WORD_OF_RECALL)) {
932  "You feel a force starting to build up inside you.");
933  return 1;
934  }
935 
936  dummy = create_archetype(FORCE_NAME);
937  if (dummy == NULL) {
939  "Oops, program error!");
940  LOG(llevError, "cast_word_of_recall: create_archetype(force) failed!\n");
941  return 0;
942  }
943  time = spell_ob->duration-SP_level_duration_adjust(caster, spell_ob);
944  if (time < 1)
945  time = 1;
946 
947  /* value of speed really doesn't make much difference, as long as it is
948  * positive. Lower value may be useful so that the problem doesn't
949  * do anything really odd if it say a -1000 or something.
950  */
951  dummy->speed = 0.002;
952  object_update_speed(dummy);
953  dummy->speed_left = -dummy->speed*time;
954  dummy->type = SPELL_EFFECT;
955  dummy->subtype = SP_WORD_OF_RECALL;
956 
957  /* If we could take advantage of enter_player_savebed() here, it would be
958  * nice, but until the map load fails, we can't.
959  */
960  EXIT_PATH(dummy) = add_string(op->contr->savebed_map);
961  EXIT_X(dummy) = op->contr->bed_x;
962  EXIT_Y(dummy) = op->contr->bed_y;
963 
964  (void)object_insert_in_ob(dummy, op);
966  "You feel a force starting to build up inside you.");
967  return 1;
968 }
969 
985 int cast_wonder(object *op, object *caster, int dir, object *spell_ob) {
986  object *newspell;
987 
988  if (!rndm(0, 3))
989  return cast_cone(op, caster, dir, spell_ob);
990 
991  if (spell_ob->randomitems) {
992  newspell = generate_treasure(spell_ob->randomitems, caster->level);
993  if (!newspell) {
994  LOG(llevError, "cast_wonder: Unable to get a spell!\n");
995  return 0;
996  }
997  if (newspell->type != SPELL) {
998  LOG(llevError, "cast_wonder: spell returned is not a spell (%d, %s)!\n", newspell->type, newspell->name);
999  return 0;
1000  }
1001  /* Prevent inifinite recursion */
1002  if (newspell->subtype == SP_WONDER) {
1003  LOG(llevError, "cast_wonder: spell returned is another wonder spell!\n");
1004  return 0;
1005  }
1006  return cast_spell(op, caster, dir, newspell, NULL);
1007  }
1008  return 1;
1009 }
1010 
1019 int perceive_self(object *op) {
1020  char *cp, buf[MAX_BUF];
1021  archetype *at = try_find_archetype(ARCH_DEPLETION);
1022  if (at == NULL) {
1023  return 1;
1024  }
1025  object *tmp;
1026  const object *god;
1027  int i;
1028  StringBuffer *immunity;
1029 
1030  god = find_god(determine_god(op));
1031  if (god)
1033  "You worship %s",
1034  god->name);
1035  else
1037  "You worship no god");
1038 
1039  tmp = arch_present_in_ob(at, op);
1040 
1041  cp = stringbuffer_finish(describe_item(op, op, 0, NULL));
1042 
1043  if (*cp == '\0' && tmp == NULL)
1045  "You feel very mundane");
1046  else {
1048  "You have:");
1050  cp);
1051  if (tmp != NULL) {
1052  for (i = 0; i < NUM_STATS; i++) {
1053  if (get_attr_value(&tmp->stats, i) < 0) {
1055  "Your %s is depleted by %d",
1056  statname[i], -(get_attr_value(&tmp->stats, i)));
1057  }
1058  }
1059  }
1060  }
1061  free(cp);
1062 
1063  if (op->glow_radius > 0)
1065  "You glow in the dark.");
1066 
1067  immunity = NULL;
1068  for (tmp = op->inv; tmp; tmp = tmp->below) {
1069  if (tmp->type == SIGN) {
1070  if (immunity == NULL) {
1071  immunity = stringbuffer_new();
1072  stringbuffer_append_string(immunity, "You have been exposed to: ");
1073  } else {
1074  stringbuffer_append_string(immunity, ", ");
1075  }
1076  stringbuffer_append_string(immunity, tmp->name);
1077  if (tmp->level > 100)
1078  stringbuffer_append_string(immunity, " (full immunity)");
1079  else if (tmp->level > 70)
1080  stringbuffer_append_string(immunity, " (high immunity)");
1081  else if (tmp->level > 20)
1082  stringbuffer_append_string(immunity, " (partial immunity)");
1083  }
1084  }
1085 
1086  if (immunity != NULL) {
1087  cp = stringbuffer_finish(immunity);
1089  free(cp);
1090  }
1091 
1092  if (is_dragon_pl(op)) {
1093  /* now grab the 'dragon_ability'-force from the player's inventory */
1094  tmp = object_find_by_type_and_arch_name(op, FORCE, "dragon_ability_force");
1095  if (tmp != NULL) {
1096  StringBuffer *levels = NULL;
1097  int i;
1098 
1099  if (tmp->stats.exp == 0) {
1100  snprintf(buf, sizeof(buf), "Your metabolism isn't focused on anything.");
1101  } else {
1102  snprintf(buf, sizeof(buf), "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]);
1103  }
1105  buf);
1106 
1107  for (i = 0; i < NROFATTACKS; i++) {
1108  if (atnr_is_dragon_enabled(i) && tmp->resist[i] > 0) {
1109  if (levels == NULL) {
1110  levels = stringbuffer_new();
1111  stringbuffer_append_string(levels, "Ability levels:\n");
1112  }
1113  stringbuffer_append_printf(levels, "- %s: %d\n", change_resist_msg[i], tmp->resist[i]);
1114  }
1115  }
1116 
1117  if (levels != NULL) {
1118  cp = stringbuffer_finish(levels);
1120  free(cp);
1121  }
1122  }
1123  }
1124  return 1;
1125 }
1126 
1127 static object* town_portal_find_force(object* op, object* spell) {
1128  object *dummy, *force;
1129 
1130  /* The first thing to do is to check if we have a marked destination
1131  * dummy is used to make a check inventory for the force
1132  */
1133  dummy = arch_to_object(spell->other_arch);
1134  if (dummy == NULL) {
1136  "Oops, program error!");
1137  LOG(llevError, "object_new failed (force in cast_create_town_portal for %s!\n", op->name);
1138  return NULL;
1139  }
1140 
1141  force = check_inv_recursive(op, dummy);
1142  if (force == NULL) {
1143  /* Here we know there is no destination marked up.
1144  * We have 2 things to do:
1145  * 1. Mark the destination in the player inventory.
1146  * 2. Let the player know it worked.
1147  */
1148  free_string(dummy->name);
1149  dummy->name = add_string(op->map->path);
1150  EXIT_X(dummy) = op->x;
1151  EXIT_Y(dummy) = op->y;
1152  dummy->weapontype = op->map->last_reset_time;
1153  object_insert_in_ob(dummy, op);
1155  "You fix this place in your mind and feel that you "
1156  "can come here from anywhere.");
1157  } else {
1158  object_free(dummy, FREE_OBJ_NO_DESTROY_CALLBACK);
1159  }
1160  return force;
1161 }
1162 
1166 static int town_portal_destroy_existing(object* op, object* spell) {
1167  object* dummy = create_archetype(spell->race);
1168  object* old_force;
1169  if (dummy == NULL) {
1171  "Oops, program error!");
1172  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1173  return 0;
1174  }
1175  archetype *perm_portal;
1176  perm_portal = try_find_archetype(spell->slaying);
1177  if (perm_portal == NULL) {
1179  "Oops, program error!");
1180  return 0;
1181  }
1182 
1183  /* To kill a town portal, we go trough the player's inventory,
1184  * for each marked portal in player's inventory,
1185  * -We try load the associated map (if impossible, consider the portal destructed)
1186  * -We find any portal in the specified location.
1187  * If it has the good name, we destruct it.
1188  * -We destruct the force indicating that portal.
1189  */
1190  while ((old_force = check_inv_recursive(op, dummy))) {
1191  int16_t exitx = EXIT_X(old_force);
1192  int16_t exity = EXIT_Y(old_force);
1193  LOG(llevDebug, "Trying to kill a portal in %s (%d,%d)\n", old_force->race, exitx, exity);
1194 
1195  mapstruct *exitmap;
1196  if (!strncmp(old_force->race, settings.localdir, strlen(settings.localdir)))
1197  exitmap = ready_map_name(old_force->race, MAP_PLAYER_UNIQUE);
1198  else
1199  exitmap = ready_map_name(old_force->race, 0);
1200 
1201  if (exitmap) {
1202  object* tmp = map_find_by_archetype(exitmap, exitx, exity, perm_portal);
1204  if (tmp->name == old_force->name) {
1205  object_remove(tmp);
1206  object_free(tmp, 0);
1207  break;
1208  }
1210 
1211  /* kill any opening animation there is */
1212  archetype *arch = try_find_archetype("town_portal_open");
1213  if (arch != NULL) {
1214  tmp = map_find_by_archetype(exitmap, exitx, exity, arch);
1216  if (tmp->name == old_force->name) {
1217  object_remove(tmp);
1218  object_free(tmp, FREE_OBJ_FREE_INVENTORY);
1219  break;
1220  }
1222  }
1223  }
1224  object_remove(old_force);
1225  object_free(old_force, 0);
1226  }
1227  object_free(dummy, FREE_OBJ_NO_DESTROY_CALLBACK);
1228  return 0;
1229 }
1230 
1260 int cast_create_town_portal(object *op, object *caster, object *spell, int dir) {
1261  object *dummy, *force, *tmp;
1262  char portal_name [1024], portal_message [1024];
1263  mapstruct *exitmap;
1264  int op_level, x, y;
1265 
1266  /* Check to see if the map the player is currently on is a per player unique
1267  * map. This can be determined in that per player unique maps have the
1268  * full pathname listed. Ignore if settings.create_home_portals is true.
1269  */
1271  if (!strncmp(op->map->path, settings.localdir, strlen(settings.localdir))) {
1273  "You can't cast that here.");
1274  return 0;
1275  }
1276  }
1277 
1278  /* Check to see if the player is on a transport */
1279  if (op->contr && op->contr->transport) {
1281  "You need to exit the transport to cast that.");
1282  return 0;
1283  }
1284 
1285  force = town_portal_find_force(op, spell);
1286  if (force == NULL) {
1287  return 1;
1288  }
1289 
1290  /* Here we know where the town portal should go to
1291  * We should kill any existing portal associated with the player.
1292  * Than we should create the 2 portals.
1293  * For each of them, we need:
1294  * - To create the portal with the name of the player+destination map
1295  * - set the owner of the town portal
1296  * - To mark the position of the portal in the player's inventory
1297  * for easier destruction.
1298  *
1299  * The mark works has follow:
1300  * slaying: Existing town portal
1301  * hp, sp : x & y of the associated portal
1302  * name : name of the portal
1303  * race : map the portal is in
1304  */
1305  if (town_portal_destroy_existing(op, spell) != 0) {
1306  return 1;
1307  }
1308 
1309  /* Creating the portals.
1310  * The very first thing to do is to ensure
1311  * access to the destination map.
1312  * If we can't, don't fizzle. Simply warn player.
1313  * This ensure player pays his mana for the spell
1314  * because HE is responsible for forgetting.
1315  * 'force' is the destination of the town portal, which we got
1316  * from the players inventory above.
1317  */
1318 
1319  /* Ensure exit map is loaded*/
1320  if (!strncmp(force->name, settings.localdir, strlen(settings.localdir)))
1321  exitmap = ready_map_name(force->name, MAP_PLAYER_UNIQUE);
1322  else
1323  exitmap = ready_map_name(force->name, 0);
1324 
1325  /* If we were unable to load (ex. random map deleted), warn player*/
1326  if (exitmap == NULL) {
1328  "Something strange happens. You can't remember where to go!?");
1329  object_remove(force);
1330  object_free(force, 0);
1331  cast_create_obj(op, create_archetype(ARCH_PORTAL_FAILED), 0);
1332  return 1;
1333  } else if (exitmap->last_reset_time != force->weapontype) {
1335  "The spell effect has expired.");
1336  object_remove(force);
1337  object_free(force, 0);
1338  cast_create_obj(op, create_archetype(ARCH_PORTAL_FAILED), 0);
1339  return 1;
1340  }
1341 
1342  op_level = caster_level(caster, spell);
1343  if (op_level < 15)
1344  snprintf(portal_message, 1024, "The air moves around you and a huge smell of ammonia surrounds you as you pass through %s's tiny portal. Pouah!", op->name);
1345  else if (op_level < 30)
1346  snprintf(portal_message, 1024, "%s's portal smells of ozone. You do a lot of movements and finally pass through the small hole in the air.", op->name);
1347  else if (op_level < 60)
1348  snprintf(portal_message, 1024, "A shining door opens in the air in front of you, showing you the path to another place.");
1349  else
1350  snprintf(portal_message, 1024, "As you walk through %s's portal, flowers come out from the ground around you. You feel awed.", op->name);
1351 
1352  /* Create a portal in front of player
1353  * dummy contain the portal and
1354  * force contain the track to kill it later
1355  */
1356 
1357  snprintf(portal_name, 1024, "%s's portal to %s", op->name, force->name);
1358  dummy = create_archetype(spell->slaying); /*The portal*/
1359  if (dummy == NULL) {
1361  "Oops, program error!");
1362  LOG(llevError, "object_new failed (perm_magic_portal) in cast_create_town_portal for %s!\n", op->name);
1363  return 0;
1364  }
1365  EXIT_PATH(dummy) = add_string(force->name);
1366  EXIT_X(dummy) = EXIT_X(force);
1367  EXIT_Y(dummy) = EXIT_Y(force);
1368  FREE_AND_COPY(dummy->name, portal_name);
1369  FREE_AND_COPY(dummy->name_pl, portal_name);
1370  object_set_msg(dummy, portal_message);
1371  dummy->race = add_string(op->name); /*Save the owner of the portal*/
1372 
1373  /* create a nice animation */
1374  tmp = create_archetype("town_portal_open");
1375  FREE_AND_COPY(tmp->name, portal_name);
1376  FREE_AND_COPY(tmp->name_pl, portal_name);
1377  object_insert_in_ob(dummy, tmp);
1378  /* and put it on the floor, when it ends the portal will be on the ground */
1379  cast_create_obj(op, tmp, 0);
1380  x = tmp->x;
1381  y = tmp->y;
1382 
1383  /* Now we need to to create a town portal marker inside the player
1384  * object, so on future castings, we can know that he has an active
1385  * town portal.
1386  */
1387  tmp = create_archetype(spell->race);
1388  if (tmp == NULL) {
1390  "Oops, program error!");
1391  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1392  return 0;
1393  }
1394  tmp->race = add_string(op->map->path);
1395  FREE_AND_COPY(tmp->name, portal_name);
1396  EXIT_X(tmp) = x;
1397  EXIT_Y(tmp) = y;
1398  object_insert_in_ob(tmp, op);
1399 
1400  /* Create a portal in the destination map
1401  * dummy contain the portal and
1402  * force the track to kill it later
1403  * the 'force' variable still contains the 'reminder' of
1404  * where this portal goes to.
1405  */
1406  snprintf(portal_name, 1024, "%s's portal to %s", op->name, op->map->path);
1407  dummy = create_archetype(spell->slaying); /*The portal*/
1408  if (dummy == NULL) {
1410  "Oops, program error!");
1411  LOG(llevError, "object_new failed (perm_magic_portal) in cast_create_town_portal for %s!\n", op->name);
1412  return 0;
1413  }
1414  EXIT_PATH(dummy) = add_string(op->map->path);
1415  EXIT_X(dummy) = op->x;
1416  EXIT_Y(dummy) = op->y;
1417  FREE_AND_COPY(dummy->name, portal_name);
1418  FREE_AND_COPY(dummy->name_pl, portal_name);
1419  object_set_msg(dummy, portal_message);
1420  dummy->race = add_string(op->name); /*Save the owner of the portal*/
1421 
1422  /* animation here too */
1423  tmp = create_archetype("town_portal_open");
1424  FREE_AND_COPY(tmp->name, portal_name);
1425  FREE_AND_COPY(tmp->name_pl, portal_name);
1426  object_insert_in_ob(dummy, tmp);
1427  /* and put it on the floor, when it ends the portal will be on the ground */
1428  object_insert_in_map_at(tmp, exitmap, op, 0, EXIT_X(force), EXIT_Y(force));
1429  x = tmp->x;
1430  y = tmp->y;
1431 
1432  /* Now we create another town portal marker that
1433  * points back to the one we just made
1434  */
1435  tmp = create_archetype(spell->race);
1436  if (tmp == NULL) {
1438  "Oops, program error!");
1439  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1440  return 0;
1441  }
1442  tmp->race = add_string(force->name);
1443  FREE_AND_COPY(tmp->name, portal_name);
1444  EXIT_X(tmp) = x;
1445  EXIT_Y(tmp) = y;
1446  object_insert_in_ob(tmp, op);
1447 
1448  /* Describe the player what happened
1449  */
1451  "You see air moving and showing you the way home.");
1452  object_remove(force); /* Delete the force inside the player*/
1453  object_free(force, 0);
1454  return 1;
1455 }
1456 
1457 
1475 int magic_wall(object *op, object *caster, int dir, object *spell_ob) {
1476  object *tmp, *tmp2;
1477  int i, posblocked, negblocked, maxrange;
1478  int16_t x, y;
1479  mapstruct *m;
1480  const char *name;
1481  archetype *at;
1482 
1483  if (!dir) {
1484  dir = op->facing;
1485  x = op->x;
1486  y = op->y;
1487  } else {
1488  x = op->x+freearr_x[dir];
1489  y = op->y+freearr_y[dir];
1490  }
1491  m = op->map;
1492 
1493  if ((spell_ob->move_block || x != op->x || y != op->y)
1494  && (get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE)
1495  || ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) == spell_ob->move_block))) {
1497  "Something is in the way.");
1498  return 0;
1499  }
1500  if (spell_ob->other_arch) {
1501  tmp = arch_to_object(spell_ob->other_arch);
1502  } else if (spell_ob->race) {
1503  char buf1[MAX_BUF];
1504 
1505  snprintf(buf1, sizeof(buf1), spell_ob->race, dir);
1506  at = try_find_archetype(buf1);
1507  if (!at) {
1508  LOG(llevError, "summon_wall: Unable to find archetype %s\n", buf1);
1510  "This spell is broken.");
1511  return 0;
1512  }
1513  tmp = arch_to_object(at);
1514  } else {
1515  LOG(llevError, "magic_wall: spell %s lacks other_arch\n", spell_ob->name);
1516  return 0;
1517  }
1518 
1519  if (tmp->type == SPELL_EFFECT) {
1520  tmp->attacktype = spell_ob->attacktype;
1521  tmp->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1522  tmp->stats.dam = spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob);
1523  tmp->range = 0;
1524  } else if (QUERY_FLAG(tmp, FLAG_ALIVE)) {
1525  tmp->stats.hp = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1526  tmp->stats.maxhp = tmp->stats.hp;
1527  object_set_owner(tmp, op);
1528  set_spell_skill(op, caster, spell_ob, tmp);
1529  }
1530  if (QUERY_FLAG(spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG(tmp, FLAG_IS_USED_UP)) {
1531  tmp->stats.food = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1532  SET_FLAG(tmp, FLAG_IS_USED_UP);
1533  }
1534  if (QUERY_FLAG(spell_ob, FLAG_TEAR_DOWN)) {
1535  tmp->stats.hp = spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob);
1536  tmp->stats.maxhp = tmp->stats.hp;
1537  SET_FLAG(tmp, FLAG_TEAR_DOWN);
1538  SET_FLAG(tmp, FLAG_ALIVE);
1539  }
1540 
1541  /* This can't really hurt - if the object doesn't kill anything,
1542  * these fields just won't be used.
1543  */
1544  object_set_owner(tmp, op);
1545  set_spell_skill(op, caster, spell_ob, tmp);
1546  tmp->level = caster_level(caster, spell_ob)/2;
1547 
1548  name = tmp->name;
1549  if ((tmp = object_insert_in_map_at(tmp, m, op, 0, x, y)) == NULL) {
1551  "Something destroys your %s",
1552  name);
1553  return 0;
1554  }
1555  /* If this is a spellcasting wall, need to insert the spell object */
1556  if (tmp->other_arch && tmp->other_arch->clone.type == SPELL)
1557  object_insert_in_ob(arch_to_object(tmp->other_arch), tmp);
1558 
1559  /* This code causes the wall to extend some distance in
1560  * each direction, or until an obstruction is encountered.
1561  * posblocked and negblocked help determine how far the
1562  * created wall can extend, it won't go extend through
1563  * blocked spaces.
1564  */
1565  maxrange = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
1566  posblocked = 0;
1567  negblocked = 0;
1568 
1569  for (i = 1; i <= maxrange; i++) {
1570  int dir2;
1571 
1572  dir2 = (dir < 4) ? (dir+2) : dir-2;
1573 
1574  x = tmp->x+i*freearr_x[dir2];
1575  y = tmp->y+i*freearr_y[dir2];
1576  m = tmp->map;
1577 
1578  if (!(get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE))
1579  && ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block)
1580  && !posblocked) {
1581  tmp2 = object_new();
1582  object_copy(tmp, tmp2);
1583  object_insert_in_map_at(tmp2, m, op, 0, x, y);
1584  /* If this is a spellcasting wall, need to insert the spell object */
1585  if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
1586  object_insert_in_ob(arch_to_object(tmp2->other_arch), tmp2);
1587  } else
1588  posblocked = 1;
1589 
1590  x = tmp->x-i*freearr_x[dir2];
1591  y = tmp->y-i*freearr_y[dir2];
1592  m = tmp->map;
1593 
1594  if (!(get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE))
1595  && ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block)
1596  && !negblocked) {
1597  tmp2 = object_new();
1598  object_copy(tmp, tmp2);
1599  object_insert_in_map_at(tmp2, m, op, 0, x, y);
1600  if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
1601  object_insert_in_ob(arch_to_object(tmp2->other_arch), tmp2);
1602  } else
1603  negblocked = 1;
1604  }
1605 
1606  if (QUERY_FLAG(tmp, FLAG_BLOCKSVIEW))
1607  update_all_los(op->map, op->x, op->y);
1608 
1609  return 1;
1610 }
1611 
1628 int dimension_door(object *op, object *caster, object *spob, int dir) {
1629  uint32_t dist, maxdist;
1630  int mflags;
1631  mapstruct *m;
1632  int16_t sx, sy;
1633 
1634  if (op->type != PLAYER)
1635  return 0;
1636 
1637  if (!dir) {
1639  "In what direction?");
1640  return 0;
1641  }
1642 
1643  /* Given the new outdoor maps, can't let players dimension door for
1644  * ever, so put limits in.
1645  */
1646  maxdist = spob->range+SP_level_range_adjust(caster, spob);
1647 
1648  if (op->contr->count) {
1649  if (op->contr->count > maxdist) {
1651  "You can't dimension door that far!");
1652  return 0;
1653  }
1654 
1655  for (dist = 0; dist < op->contr->count; dist++) {
1656  mflags = get_map_flags(op->map, &m,
1657  op->x+freearr_x[dir]*(dist+1),
1658  op->y+freearr_y[dir]*(dist+1),
1659  &sx, &sy);
1660 
1661  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
1662  break;
1663 
1664  if ((mflags&P_BLOCKSVIEW)
1665  && OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1666  break;
1667  }
1668 
1669  if (dist < op->contr->count) {
1671  "Something blocks the magic of the spell.");
1672  op->contr->count = 0;
1673  return 0;
1674  }
1675  op->contr->count = 0;
1676 
1677  /* Remove code that puts player on random space on maps. IMO,
1678  * a lot of maps probably have areas the player should not get to,
1679  * but may not be marked as NO_MAGIC (as they may be bounded
1680  * by such squares). Also, there are probably treasure rooms and
1681  * lots of other maps that protect areas with no magic, but the
1682  * areas themselves don't contain no magic spaces.
1683  */
1684  /* This call here is really just to normalize the coordinates */
1685  mflags = get_map_flags(op->map, &m, op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist,
1686  &sx, &sy);
1687  if (mflags&P_IS_ALIVE || OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) {
1689  "You cast your spell, but nothing happens.");
1690  return 1; /* Maybe the penalty should be more severe... */
1691  }
1692  } else {
1693  /* Player didn't specify a distance, so lets see how far
1694  * we can move the player. Don't know why this stopped on
1695  * spaces that blocked the players view.
1696  */
1697 
1698  for (dist = 0; dist < maxdist; dist++) {
1699  mflags = get_map_flags(op->map, &m,
1700  op->x+freearr_x[dir]*(dist+1),
1701  op->y+freearr_y[dir]*(dist+1),
1702  &sx, &sy);
1703 
1704  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
1705  break;
1706 
1707  if ((mflags&P_BLOCKSVIEW)
1708  && OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1709  break;
1710  }
1711 
1712  /* If the destination is blocked, keep backing up until we
1713  * find a place for the player.
1714  */
1715  for (; dist > 0; dist--) {
1716  if (get_map_flags(op->map, &m, op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist, &sx, &sy)&(P_OUT_OF_MAP|P_IS_ALIVE))
1717  continue;
1718 
1719  if (!OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1720  break;
1721  }
1722  if (!dist) {
1724  "Your spell failed!");
1725  return 0;
1726  }
1727  }
1728 
1729  if (op->contr->transport && op->contr->transport->type == TRANSPORT) {
1730  ob_apply(op->contr->transport, op, 0);
1731  if (op->contr->transport) {
1733  "Your spell failed!");
1734  return 0;
1735  }
1736  }
1737 
1738  /* Actually move the player now */
1739  object_remove(op);
1740  if ((op = object_insert_in_map_at(op, op->map, op, 0, op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist)) == NULL)
1741  return 1;
1742 
1743  if (op->type == PLAYER) {
1744  map_newmap_cmd(&op->contr->socket);
1746  }
1747  op->speed_left = -FABS(op->speed)*5; /* Freeze them for a short while */
1748  return 1;
1749 }
1750 
1751 
1764 int cast_heal(object *op, object *caster, object *spell, int dir) {
1765  object *target;
1766  archetype *at;
1767  object *poison;
1768  int heal = 0, success = 0;
1769 
1770  target = find_target_for_friendly_spell(op, dir);
1771 
1772  if (target == NULL)
1773  return 0;
1774 
1775  /* Figure out how many hp this spell might cure.
1776  * could be zero if this spell heals effects, not damage.
1777  */
1778  heal = spell->stats.dam;
1779  if (spell->stats.hp)
1780  heal += random_roll(spell->stats.hp, 6, op, PREFER_HIGH)+spell->stats.hp;
1781 
1782  if (heal) {
1783  if (target->stats.hp >= target->stats.maxhp) {
1785  "You are already fully healed.");
1786  } else {
1787  /* See how many points we actually heal. Instead of messages
1788  * based on type of spell, we instead do messages based
1789  * on amount of damage healed.
1790  */
1791  if (heal > (target->stats.maxhp-target->stats.hp))
1792  heal = target->stats.maxhp-target->stats.hp;
1793  target->stats.hp += heal;
1794 
1795  if (target->stats.hp >= target->stats.maxhp) {
1797  "You feel just fine!");
1798  } else if (heal > 50) {
1800  "Your wounds close!");
1801  } else if (heal > 25) {
1803  "Your wounds mostly close.");
1804  } else if (heal > 10) {
1806  "Your wounds start to fade.");
1807  } else {
1809  "Your wounds start to close.");
1810  }
1811  success = 1;
1812  }
1813  }
1814  if (spell->attacktype&AT_DISEASE)
1815  if (cure_disease(target, op, caster && caster->type != PLAYER ? caster->skill : spell->skill))
1816  success = 1;
1817 
1818  if (spell->attacktype&AT_POISON) {
1819  at = try_find_archetype("poisoning");
1820  if (at != NULL) {
1821  poison = arch_present_in_ob(at, target);
1822  if (poison) {
1823  success = 1;
1825  "Your body feels cleansed");
1826  poison->stats.food = 1;
1827  }
1828  }
1829  }
1830  if (spell->attacktype&AT_CONFUSION) {
1831  poison = object_present_in_ob_by_name(FORCE, "confusion", target);
1832  if (poison) {
1833  success = 1;
1835  "Your mind feels clearer");
1836  poison->duration = 1;
1837  }
1838  }
1839  if (spell->attacktype&AT_BLIND) {
1840  at = try_find_archetype("blindness");
1841  if (at != NULL) {
1842  poison = arch_present_in_ob(at, target);
1843  if (poison) {
1844  success = 1;
1846  "Your vision begins to return.");
1847  poison->stats.food = 1;
1848  }
1849  }
1850  }
1851  if (spell->last_sp && target->stats.sp < target->stats.maxsp) {
1852  target->stats.sp += spell->last_sp;
1853  if (target->stats.sp > target->stats.maxsp)
1854  target->stats.sp = target->stats.maxsp;
1855  success = 1;
1857  "Magical energies surge through your body!");
1858  }
1859  if (spell->last_grace && target->stats.grace < target->stats.maxgrace) {
1860  target->stats.grace += spell->last_grace;
1861  if (target->stats.grace > target->stats.maxgrace)
1862  target->stats.grace = target->stats.maxgrace;
1863  success = 1;
1865  "You feel redeemed with you god!");
1866  }
1867  if (spell->stats.food && target->stats.food < MAX_FOOD) {
1868  target->stats.food += spell->stats.food;
1869  if (target->stats.food > MAX_FOOD)
1870  target->stats.food = MAX_FOOD;
1871  success = 1;
1872  /* We could do something a bit better like the messages for healing above */
1874  "You feel your belly fill with food");
1875  }
1876 
1877  if (spell->other_arch != NULL && target->map != NULL) {
1878  object_insert_in_map_at(arch_to_object(spell->other_arch), target->map, NULL, INS_ON_TOP, target->x, target->y);
1879  }
1880 
1881  return success;
1882 }
1883 
1884 
1890 static const char *const no_gain_msgs[NUM_STATS] = {
1891  "You grow no stronger.",
1892  "You grow no more agile.",
1893  "You don't feel any healthier.",
1894  "no wis",
1895  "You are no easier to look at.",
1896  "no int",
1897  "no pow"
1898 };
1899 
1919 int cast_change_ability(object *op, object *caster, object *spell_ob, int dir, int silent) {
1920  object *tmp;
1921  object *force = NULL;
1922  int i;
1923 
1924  /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
1925  if (dir != 0) {
1926  tmp = find_target_for_friendly_spell(op, dir);
1927  } else {
1928  tmp = op;
1929  }
1930 
1931  if (tmp == NULL)
1932  return 0;
1933 
1934  /* If we've already got a force of this type, don't add a new one. */
1935  FOR_INV_PREPARE(tmp, tmp2)
1936  if (tmp2->type == FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
1937  if (tmp2->name == spell_ob->name) {
1938  force = tmp2; /* the old effect will be "refreshed" */
1939  break;
1940  } else if (spell_ob->race && spell_ob->race == tmp2->name) {
1941  if (!silent)
1943  "You can not cast %s while %s is in effect",
1944  spell_ob->name, tmp2->name_pl);
1945  return 0;
1946  }
1947  }
1948  FOR_INV_FINISH();
1949  if (force == NULL) {
1950  force = create_archetype(FORCE_NAME);
1951  force->subtype = FORCE_CHANGE_ABILITY;
1952  free_string(force->name);
1953  if (spell_ob->race)
1954  force->name = add_refcount(spell_ob->race);
1955  else
1956  force->name = add_refcount(spell_ob->name);
1957  free_string(force->name_pl);
1958  force->name_pl = add_refcount(spell_ob->name);
1959  } else {
1960  int duration;
1961 
1962  duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
1963  if (duration > force->duration) {
1964  force->duration = duration;
1966  "You recast the spell while in effect.");
1967 
1968  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
1969  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
1970  }
1971 
1972  } else {
1974  "Recasting the spell had no effect.");
1975  }
1976  return 1;
1977  }
1978  force->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
1979  if (op->type == PLAYER)
1980  store_spell_expiry(force);
1981  force->speed = 1.0;
1982  force->speed_left = -1.0;
1983  SET_FLAG(force, FLAG_APPLIED);
1984 
1985  /* Now start processing the effects. First, protections */
1986  for (i = 0; i < NROFATTACKS; i++) {
1987  if (spell_ob->resist[i]) {
1988  force->resist[i] = spell_ob->resist[i]+SP_level_dam_adjust(caster, spell_ob);
1989  if (force->resist[i] > 100)
1990  force->resist[i] = 100;
1991  }
1992  }
1993  if (spell_ob->stats.hp)
1994  force->stats.hp = spell_ob->stats.hp+SP_level_dam_adjust(caster, spell_ob);
1995 
1996  if (tmp->type == PLAYER) {
1997  /* Stat adjustment spells */
1998  for (i = 0; i < NUM_STATS; i++) {
1999  int8_t stat = get_attr_value(&spell_ob->stats, i), k, sm;
2000 
2001  if (stat) {
2002  sm = 0;
2003  for (k = 0; k < stat; k++)
2004  sm += rndm(1, 3);
2005 
2006  if ((get_attr_value(&tmp->stats, i)+sm) > (15+5*stat)) {
2007  sm = (15+5*stat)-get_attr_value(&tmp->stats, i);
2008  if (sm < 0)
2009  sm = 0;
2010  }
2011  set_attr_value(&force->stats, i, sm);
2012  if (!sm)
2014  no_gain_msgs[i]);
2015  }
2016  }
2017  }
2018 
2019  force->move_type = spell_ob->move_type;
2020 
2021  if (QUERY_FLAG(spell_ob, FLAG_SEE_IN_DARK))
2022  SET_FLAG(force, FLAG_SEE_IN_DARK);
2023 
2024  if (QUERY_FLAG(spell_ob, FLAG_XRAYS))
2025  SET_FLAG(force, FLAG_XRAYS);
2026 
2027  /* Haste/bonus speed */
2028  if (spell_ob->stats.exp) {
2029  if (op->speed > 0.5)
2030  force->stats.exp = (float)spell_ob->stats.exp/(op->speed+0.5);
2031  else
2032  force->stats.exp = spell_ob->stats.exp;
2033  }
2034 
2035  force->stats.wc = spell_ob->stats.wc;
2036  force->stats.ac = spell_ob->stats.ac;
2037  force->attacktype = spell_ob->attacktype;
2038 
2039  SET_FLAG(tmp, FLAG_NO_FIX_PLAYER); /* we don't want object_insert_in_ob() to call fix_object. */
2040  object_insert_in_ob(force, tmp);
2042  change_abil(tmp, force); /* Display any relevant messages, and call fix_object to update the player */
2043 
2044  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
2045  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
2046  }
2047 
2048  return 1;
2049 }
2050 
2067 int cast_bless(object *op, object *caster, object *spell_ob, int dir) {
2068  int i;
2069  const object *god = find_god(determine_god(op));
2070  object *force = NULL, *tmp;
2071 
2072  /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
2073  if (dir != 0) {
2074  tmp = find_target_for_friendly_spell(op, dir);
2075  } else {
2076  tmp = op;
2077  }
2078 
2079  /* If we've already got a force of this type, don't add a new one. */
2080  FOR_INV_PREPARE(tmp, tmp2)
2081  if (tmp2->type == FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
2082  if (tmp2->name == spell_ob->name) {
2083  force = tmp2; /* the old effect will be "refreshed" */
2084  break;
2085  } else if (spell_ob->race && spell_ob->race == tmp2->name) {
2087  "You can not cast %s while %s is in effect",
2088  spell_ob->name, tmp2->name_pl);
2089  return 0;
2090  }
2091  }
2092  FOR_INV_FINISH();
2093  if (force == NULL) {
2094  force = create_archetype(FORCE_NAME);
2095  force->subtype = FORCE_CHANGE_ABILITY;
2096  free_string(force->name);
2097  if (spell_ob->race)
2098  force->name = add_refcount(spell_ob->race);
2099  else
2100  force->name = add_refcount(spell_ob->name);
2101  free_string(force->name_pl);
2102  force->name_pl = add_refcount(spell_ob->name);
2103  } else {
2104  int duration;
2105 
2106  duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
2107  if (duration > force->duration) {
2108  force->duration = duration;
2110  "You recast the spell while in effect.");
2111  } else {
2113  "Recasting the spell had no effect.");
2114  }
2115  return 0;
2116  }
2117  force->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
2118  force->speed = 1.0;
2119  force->speed_left = -1.0;
2120 
2121  if (!god) {
2123  "Your blessing seems empty.");
2124  } else {
2125  /* Only give out good benefits, and put a max on it */
2126  const int16_t resist_max = spell_ob->resist[ATNR_GODPOWER];
2127  for (i = 0; i < NROFATTACKS; i++) {
2128  if (god->resist[i] > 0) {
2129  force->resist[i] = MIN(god->resist[i], resist_max);
2130  }
2131  }
2132  // Also grant appropriate amount of godpower resistance.
2133  force->resist[ATNR_GODPOWER] = spell_ob->resist[ATNR_GODPOWER];
2134 
2135  force->path_attuned |= god->path_attuned;
2136  if (spell_ob->attacktype) {
2137  force->attacktype |= god->attacktype|AT_PHYSICAL;
2138  if (god->slaying)
2139  force->slaying = add_string(god->slaying);
2140  }
2141  if (tmp != op) {
2143  "You bless %s.",
2144  tmp->name);
2146  "%s blessed you.",
2147  op->name);
2148  } else {
2150  "You are blessed by %s!",
2151  god->name);
2152  }
2153  }
2154  force->stats.wc = spell_ob->stats.wc;
2155  force->stats.ac = spell_ob->stats.ac;
2156 
2157  store_spell_expiry(force);
2158  object_insert_in_ob(force, tmp);
2159  SET_FLAG(force, FLAG_APPLIED);
2160  change_abil(tmp, force); /* To display any messages, will call fix_object() */
2161 
2162  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
2163  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
2164  }
2165  return 1;
2166 }
2167 
2168 
2169 
2170 /*
2171  * Alchemy code by Mark Wedel
2172  *
2173  * This code adds a new spell, called alchemy. Alchemy will turn
2174  * objects to gold nuggets, the value of the gold nuggets being
2175  * from 5% to 40% of that of the item itself depending on casting level.
2176  * It uses the value of the object before charisma adjustments, because
2177  * the nuggets themselves will be will be adjusted by charisma when sold.
2178  *
2179  * Large nuggets are worth 25 gp each (base). You will always get
2180  * the maximum number of large nuggets you could get.
2181  * Small nuggets are worth 1 gp each (base). You will get from 0
2182  * to the max amount of small nuggets as you could get.
2183  *
2184  * For example, if an item is worth 110 gold, you will get
2185  * 4 large nuggets, and from 0-10 small nuggets.
2186  *
2187  * There is also a chance (1:30) that you will get nothing at all
2188  * for the object. There is also a maximum weight that will be
2189  * alchemied.
2190  */
2191 
2192 #define SMALL_NUGGET "smallnugget"
2193 #define LARGE_NUGGET "largenugget"
2194 
2209 static void alchemy_object(float value_adj, object *obj, int *small_nuggets, int *large_nuggets, int *weight) {
2210  uint64_t value = price_base(obj);
2211  uint64_t small_value, large_value;
2213  /* Multiply the value of the object by value_adj, which should range
2214  * from 0.05 to 0.40. Set value to 0 instead if unpaid.
2215  */
2216  if (QUERY_FLAG(obj, FLAG_UNPAID))
2217  value = 0;
2218  else
2219  value *= value_adj;
2220 
2221  archetype *small_nugget_arch = try_find_archetype(SMALL_NUGGET);
2222  if (small_nugget_arch == NULL) {
2223  return;
2224  }
2225  small_value = price_base(&small_nugget_arch->clone);
2226  archetype *large_nugget_arch = try_find_archetype(LARGE_NUGGET);
2227  if (large_nugget_arch == NULL) {
2228  return;
2229  }
2230  large_value = price_base(&large_nugget_arch->clone);
2231 
2232  /* Give half of what value_adj says when we alchemy money (This should
2233  * hopefully make it so that it isn't worth it to alchemy money, sell
2234  * the nuggets, alchemy the gold from that, etc.
2235  */
2236  if (value && (obj->type == MONEY || obj->type == GEM))
2237  value /= 2;
2238 
2239  if ((obj->value > 0) && rndm(0, 29)) {
2240  int count;
2241 
2242  assert(large_value != 0 && small_value != 0);
2243  count = value/large_value;
2244  *large_nuggets += count;
2245  value -= (uint64_t)count*large_value;
2246  count = value/small_value;
2247  *small_nuggets += count;
2248  }
2249 
2250  /* Turn 25 small nuggets into 1 large nugget. If the value
2251  * of large nuggets is not evenly divisable by the small nugget
2252  * value, take off an extra small_nugget (Assuming small_nuggets!=0)
2253  */
2254  if (*small_nuggets*small_value >= large_value) {
2255  assert(small_value != 0);
2256  (*large_nuggets)++;
2257  *small_nuggets -= large_value/small_value;
2258  if (*small_nuggets && large_value%small_value)
2259  (*small_nuggets)--;
2260  }
2261 
2262  if (weight != NULL) {
2263  *weight += obj->weight;
2264  }
2265 
2266  object_remove(obj);
2267  object_free(obj, FREE_OBJ_NO_DESTROY_CALLBACK);
2268 }
2269 
2283 static void place_alchemy_objects(object *op, mapstruct *m, int small_nuggets, int large_nuggets, int x, int y) {
2284  object *tmp;
2285  int flag = 0;
2286 
2287  /* Put any nuggets below the player, but we can only pass this
2288  * flag if we are on the same space as the player
2289  */
2290  if (x == op->x && y == op->y && op->map == m)
2291  flag = INS_BELOW_ORIGINATOR;
2292 
2293  if (small_nuggets) {
2295  tmp-> nrof = small_nuggets;
2296  object_insert_in_map_at(tmp, m, op, flag, x, y);
2297  }
2298  if (large_nuggets) {
2300  tmp-> nrof = large_nuggets;
2301  object_insert_in_map_at(tmp, m, op, flag, x, y);
2302  }
2303 }
2304 
2319 int alchemy(object *op, object *caster, object *spell_ob) {
2320  int x, y, weight = 0, weight_max, large_nuggets, small_nuggets, mflags;
2321  int16_t nx, ny;
2322  float value_adj;
2323  mapstruct *mp;
2324 
2325  if (op->type != PLAYER)
2326  return 0;
2327 
2328  /* Put a maximum weight of items that can be alchemied. Limits the power
2329  * some, and also prevents people from alcheming every table/chair/clock
2330  * in sight
2331  */
2332  weight_max = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
2333  weight_max *= 1000;
2334 
2335  /* Set value_adj to be a multiplier for how much of the original value
2336  * will be in the nuggets. Starts at 0.05, increasing by 0.01 per casting
2337  * level, maxing out at 0.40.
2338  */
2339  value_adj = (SP_level_dam_adjust(caster, spell_ob)/100.00)+0.05;
2340 
2341  if (value_adj > 0.40)
2342  value_adj = 0.40;
2343 
2344  for (y = op->y-1; y <= op->y+1; y++) {
2345  for (x = op->x-1; x <= op->x+1; x++) {
2346  nx = x;
2347  ny = y;
2348 
2349  mp = op->map;
2350 
2351  mflags = get_map_flags(mp, &mp, nx, ny, &nx, &ny);
2352 
2353  if (mflags&(P_OUT_OF_MAP|P_NO_MAGIC))
2354  continue;
2355 
2356  /* Treat alchemy a little differently - most spell effects
2357  * use fly as the movement type - for alchemy, consider it
2358  * ground level effect.
2359  */
2360  if (GET_MAP_MOVE_BLOCK(mp, nx, ny)&MOVE_WALK)
2361  continue;
2362 
2363  small_nuggets = 0;
2364  large_nuggets = 0;
2365 
2366  FOR_MAP_PREPARE(mp, nx, ny, tmp) {
2367  if (tmp->weight > 0 && !QUERY_FLAG(tmp, FLAG_NO_PICK)
2368  && !QUERY_FLAG(tmp, FLAG_ALIVE)
2369  && !QUERY_FLAG(tmp, FLAG_IS_CAULDRON)) {
2370  if (tmp->inv) {
2371  FOR_INV_PREPARE(tmp, tmp1)
2372  if (tmp1->weight > 0 && !QUERY_FLAG(tmp1, FLAG_NO_PICK)
2373  && !QUERY_FLAG(tmp1, FLAG_ALIVE)
2374  && !QUERY_FLAG(tmp1, FLAG_IS_CAULDRON))
2375  alchemy_object(value_adj, tmp1, &small_nuggets, &large_nuggets, &weight);
2376  FOR_INV_FINISH();
2377  }
2378  alchemy_object(value_adj, tmp, &small_nuggets, &large_nuggets, &weight);
2379 
2380  if (weight > weight_max) {
2381  place_alchemy_objects(op, mp, small_nuggets, large_nuggets, nx, ny);
2382  return 1;
2383  }
2384  } /* is alchemable object */
2385  } FOR_MAP_FINISH(); /* process all objects on this space */
2386 
2387  /* Insert all the nuggets at one time. This probably saves time, but
2388  * it also prevents us from alcheming nuggets that were just created
2389  * with this spell.
2390  */
2391  place_alchemy_objects(op, mp, small_nuggets, large_nuggets, nx, ny);
2392  }
2393  }
2394 
2395  /* reset this so that if player standing on a big pile of stuff,
2396  * it is redrawn properly.
2397  */
2398  op->contr->socket.look_position = 0;
2399  return 1;
2400 }
2401 
2402 
2417 int remove_curse(object *op, object *caster, object *spell) {
2418  int success = 0, was_one = 0;
2419 
2420  FOR_INV_PREPARE(op, tmp)
2421  if (QUERY_FLAG(tmp, FLAG_APPLIED)
2422  && ((QUERY_FLAG(tmp, FLAG_CURSED) && QUERY_FLAG(spell, FLAG_CURSED))
2423  || (QUERY_FLAG(tmp, FLAG_DAMNED) && QUERY_FLAG(spell, FLAG_DAMNED)))) {
2424  was_one++;
2425  if (tmp->level <= caster_level(caster, spell)) {
2426  success++;
2427  if (QUERY_FLAG(spell, FLAG_DAMNED))
2428  CLEAR_FLAG(tmp, FLAG_DAMNED);
2429 
2430  CLEAR_FLAG(tmp, FLAG_CURSED);
2432  tmp->value = 0; /* Still can't sell it */
2433  if (op->type == PLAYER)
2434  esrv_update_item(UPD_FLAGS, op, tmp);
2435  }
2436  }
2437  FOR_INV_FINISH();
2438 
2439  if (op->type == PLAYER) {
2440  if (success) {
2442  "You feel like some of your items are looser now.");
2443  } else {
2444  if (was_one)
2446  "You failed to remove the curse.");
2447  else
2449  "You are not using any cursed items.");
2450  }
2451  }
2452  return success;
2453 }
2454 
2467 int cast_item_curse_or_curse(object *op, object *caster, object *spell_ob) {
2468  object *marked = find_marked_object(op);
2469  char name[HUGE_BUF];
2470 
2471  if (!marked) {
2473  "You need to mark an item first!");
2474  return 0;
2475  }
2476 
2477  if ((QUERY_FLAG(marked, FLAG_CURSED) && QUERY_FLAG(spell_ob, FLAG_CURSED))
2478  || (QUERY_FLAG(marked, FLAG_BLESSED) && QUERY_FLAG(spell_ob, FLAG_BLESSED))) {
2480  "The spell has no effect");
2481  return 0;
2482  }
2483 
2484  query_short_name(marked, name, HUGE_BUF);
2485  if (QUERY_FLAG(spell_ob, FLAG_CURSED)) {
2487  "Your %s emits a dark light for a few seconds.", name);
2488  SET_FLAG(marked, FLAG_CURSED);
2489  CLEAR_FLAG(marked, FLAG_KNOWN_CURSED);
2490  CLEAR_FLAG(marked, FLAG_IDENTIFIED);
2491  esrv_update_item(UPD_FLAGS, op, marked);
2492  return 1;
2493  }
2494 
2496  "Your %s glows blue for a few seconds.", name);
2497  SET_FLAG(marked, FLAG_BLESSED);
2498  SET_FLAG(marked, FLAG_KNOWN_BLESSED);
2499  SET_FLAG(marked, FLAG_STARTEQUIP);
2500  esrv_update_item(UPD_FLAGS, op, marked);
2501  return 1;
2502 }
2503 
2518 int cast_identify(object *op, object *caster, object *spell) {
2519  int success = 0, num_ident;
2520  char desc[MAX_BUF];
2521 
2522  num_ident = spell->stats.dam+SP_level_dam_adjust(caster, spell);
2523 
2524  if (num_ident < 1)
2525  num_ident = 1;
2526 
2527  FOR_INV_PREPARE(op, tmp)
2528  if (!tmp->invisible && !is_identified(tmp)) {
2529  tmp = identify(tmp);
2530  if (op->type == PLAYER) {
2532  "You have %s.",
2533  ob_describe(tmp, op, 1, desc, sizeof(desc)));
2534  if (tmp->msg) {
2536  "The item has a story:\n%s",
2537  tmp->msg);
2538  }
2539  }
2540  num_ident--;
2541  success = 1;
2542  if (!num_ident)
2543  break;
2544  }
2545  FOR_INV_FINISH();
2546  /* If all the power of the spell has been used up, don't go and identify
2547  * stuff on the floor. Only identify stuff on the floor if the spell
2548  * was not fully used.
2549  */
2550  if (num_ident) {
2551  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp)
2552  if (!tmp->invisible && !is_identified(tmp)) {
2553  tmp = identify(tmp);
2554  if (op->type == PLAYER) {
2556  "On the ground is %s.",
2557  ob_describe(tmp, op, 1, desc, sizeof(desc)));
2558  if (tmp->msg) {
2560  "The item has a story:\n%s",
2561  tmp->msg);
2562  }
2564  }
2565  num_ident--;
2566  success = 1;
2567  if (!num_ident)
2568  break;
2569  }
2570  FOR_MAP_FINISH();
2571  }
2572  if (!success)
2574  "You can't reach anything unidentified.");
2575  else {
2576  spell_effect(spell, op->x, op->y, op->map, op);
2577  }
2578  return success;
2579 }
2580 
2593 int cast_detection(object *op, object *caster, object *spell) {
2594  object *tmp, *last, *detect;
2595  const object *god;
2596  int done_one, range, mflags, floor, level;
2597  int16_t x, y, nx, ny;
2598  mapstruct *m;
2599 
2600  /* We precompute some values here so that we don't have to keep
2601  * doing it over and over again.
2602  */
2603  god = find_god(determine_god(op));
2604  level = caster_level(caster, spell);
2605  range = spell->range+SP_level_range_adjust(caster, spell);
2606 
2607  for (x = op->x-range; x <= op->x+range; x++)
2608  for (y = op->y-range; y <= op->y+range; y++) {
2609  m = op->map;
2610  mflags = get_map_flags(m, &m, x, y, &nx, &ny);
2611  if (mflags&P_OUT_OF_MAP)
2612  continue;
2613 
2614  /* For most of the detections, we only detect objects above the
2615  * floor. But this is not true for show invisible.
2616  * Basically, we just go and find the top object and work
2617  * down - that is easier than working up.
2618  */
2619 
2620  last = NULL;
2621  FOR_MAP_PREPARE(m, nx, ny, tmp)
2622  last = tmp;
2623  FOR_MAP_FINISH();
2624  /* Shouldn't happen, but if there are no objects on a space, this
2625  * would happen.
2626  */
2627  if (!last)
2628  continue;
2629 
2630  done_one = 0;
2631  floor = 0;
2632  detect = NULL;
2633  tmp = last;
2635  /* show invisible */
2636  if (QUERY_FLAG(spell, FLAG_MAKE_INVIS)
2637  /* Might there be other objects that we can make visibile? */
2638  && (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) ||
2639  (tmp->type == PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)) ||
2640  tmp->type == CF_HANDLE ||
2641  tmp->type == TRAPDOOR || tmp->type == EXIT || tmp->type == HOLE ||
2642  tmp->type == BUTTON || tmp->type == TELEPORTER ||
2643  tmp->type == GATE || tmp->type == LOCKED_DOOR ||
2644  tmp->type == WEAPON || tmp->type == ALTAR || tmp->type == SIGN ||
2645  tmp->type == TRIGGER_PEDESTAL || tmp->type == SPECIAL_KEY ||
2646  tmp->type == TREASURE || tmp->type == BOOK ||
2647  tmp->type == HOLY_ALTAR))) {
2648  if (random_roll(0, level-1, op, PREFER_HIGH) > tmp->level) {
2649  tmp->invisible = 0;
2650  done_one = 1;
2651  }
2652  }
2653  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
2654  floor = 1;
2655 
2656  /* All detections below this point don't descend beneath the floor,
2657  * so just continue on. We could be clever and look at the type of
2658  * detection to completely break out if we don't care about objects beneath
2659  * the floor, but once we get to the floor, not likely a very big issue anyways.
2660  */
2661  if (floor)
2662  continue;
2663 
2664  /* I had thought about making detect magic and detect curse
2665  * show the flash the magic item like it does for detect monster.
2666  * however, if the object is within sight, this would then make it
2667  * difficult to see what object is magical/cursed, so the
2668  * effect wouldn't be as apparent.
2669  */
2670 
2671  /* detect magic */
2672  if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)
2673  && !QUERY_FLAG(tmp, FLAG_KNOWN_MAGICAL)
2674  && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)
2675  && is_magical(tmp)) {
2677  /* make runes more visible */
2678  if (tmp->type == RUNE && tmp->attacktype&AT_MAGIC)
2679  tmp->stats.Cha /= 4;
2680  done_one = 1;
2681  }
2682  /* detect monster */
2683  if (QUERY_FLAG(spell, FLAG_MONSTER)
2684  && (QUERY_FLAG(tmp, FLAG_MONSTER) || (tmp->type == PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)))) {
2685  done_one = 2;
2686  if (!detect)
2687  detect = tmp;
2688  }
2689  /* Basically, if race is set in the spell, then the creatures race must
2690  * match that. if the spell race is set to GOD, then the gods opposing
2691  * race must match.
2692  */
2693  if (spell->race
2694  && QUERY_FLAG(tmp, FLAG_MONSTER)
2695  && tmp->race
2696  && ((!strcmp(spell->race, "GOD") && god && god->slaying && strstr(god->slaying, tmp->race)) || (strstr(spell->race, tmp->race)))) {
2697  done_one = 2;
2698  if (!detect)
2699  detect = tmp;
2700  }
2701  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED)
2702  && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED)
2703  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
2705  done_one = 1;
2706  }
2707  } FOR_OB_AND_BELOW_FINISH(); /* for stack of objects on this space */
2708 
2709  /* Code here puts an effect of the spell on the space, so you can see
2710  * where the magic is.
2711  */
2712  if (done_one) {
2713  object *detect_ob;
2714  int dx = nx, dy = ny;
2715 
2716  /* if this is set, we want to copy the face */
2717  if (done_one == 2 && detect) {
2718  /*
2719  * We can't simply copy the face to a single item, because
2720  * multipart objects need to have multipart glows.
2721  * So copy the initial item, erase some properties, and use that.
2722  */
2723 
2724  object *part;
2725  int flag;
2726 
2727  dx = HEAD(detect)->x;
2728  dy = HEAD(detect)->y;
2729 
2730  detect_ob = object_create_arch(HEAD(detect)->arch);
2731  for (part = detect_ob; part != NULL; part = part->more) {
2732  if (part->arch->reference_count > 0)
2733  part->arch->reference_count++;
2734  part->last_anim = 0;
2735  part->type = spell->other_arch->clone.type;
2736  for (flag = 0; flag < 4; flag++) {
2737  part->flags[flag] = spell->other_arch->clone.flags[flag];
2738  }
2739  part->stats.food = spell->other_arch->clone.stats.food;
2740  part->last_anim = 0;
2741  part->speed = spell->other_arch->clone.speed;
2742  part->speed_left = spell->other_arch->clone.speed_left;
2743  part->move_allow = spell->other_arch->clone.move_allow;
2744  part->move_block = spell->other_arch->clone.move_block;
2745  part->move_type = spell->other_arch->clone.move_type;
2746  part->glow_radius = spell->other_arch->clone.glow_radius;
2747  part->invisible = spell->other_arch->clone.invisible;
2748  part->weight = spell->other_arch->clone.weight;
2749  part->map_layer = spell->other_arch->clone.map_layer;
2750  FREE_AND_COPY(part->name, spell->other_arch->clone.name);
2751 
2752  /* by default, the detect_ob is already animated */
2753  if (!QUERY_FLAG(detect, FLAG_ANIMATE))
2754  CLEAR_FLAG(part, FLAG_ANIMATE);
2755  }
2756  object_update_speed(detect_ob);
2757  } else
2758  detect_ob = arch_to_object(spell->other_arch);
2759 
2760  object_insert_in_map_at(detect_ob, m, op, 0, dx, dy);
2761  }
2762  } /* for processing the surrounding spaces */
2763 
2764 
2765  /* Now process objects in the players inventory if detect curse or magic */
2766  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) || QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)) {
2767  done_one = 0;
2768  FOR_INV_PREPARE(op, tmp) {
2769  if (!tmp->invisible && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)) {
2770  if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)
2771  && is_magical(tmp)
2772  && !QUERY_FLAG(tmp, FLAG_KNOWN_MAGICAL)) {
2774  if (op->type == PLAYER)
2775  esrv_send_item(op, tmp);
2776  }
2777  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED)
2778  && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED)
2779  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
2781  if (op->type == PLAYER)
2782  esrv_send_item(op, tmp);
2783  }
2784  } /* if item is not identified */
2785  } FOR_INV_FINISH(); /* for the players inventory */
2786  } /* if detect magic/curse and object is a player */
2787  return 1;
2788 }
2789 
2797 static void charge_mana_effect(object *victim, int caster_level) {
2798  /* Prevent explosions for objects without mana. Without this check, doors
2799  * will explode, too.
2800  */
2801  if (victim->stats.maxsp <= 0)
2802  return;
2803 
2805  "You feel energy course through you.");
2806 
2807  if (victim->stats.sp >= victim->stats.maxsp*2) {
2808  object *tmp;
2809 
2811  "Your head explodes!");
2812 
2813  /* Explodes a fireball centered at player */
2815  tmp->dam_modifier = random_roll(1, caster_level, victim, PREFER_LOW)/5+1;
2816  tmp->stats.maxhp = random_roll(1, caster_level, victim, PREFER_LOW)/10+2;
2817  object_insert_in_map_at(tmp, victim->map, NULL, 0, victim->x, victim->y);
2818  victim->stats.sp = 2*victim->stats.maxsp;
2819  } else if (victim->stats.sp >= victim->stats.maxsp*1.88) {
2821  "You feel like your head is going to explode.");
2822  } else if (victim->stats.sp >= victim->stats.maxsp*1.66) {
2824  "You get a splitting headache!");
2825  } else if (victim->stats.sp >= victim->stats.maxsp*1.5) {
2827  "Chaos fills your world.");
2828  confuse_living(victim, victim, 99);
2829  } else if (victim->stats.sp >= victim->stats.maxsp*1.25) {
2831  "You start hearing voices.");
2832  }
2833 }
2834 
2852 int cast_transfer(object *op, object *caster, object *spell, int dir) {
2853  object *plyr = NULL;
2854  int16_t x, y;
2855  mapstruct *m;
2856  int mflags;
2857 
2858  m = op->map;
2859  x = op->x+freearr_x[dir];
2860  y = op->y+freearr_y[dir];
2861 
2862  mflags = get_map_flags(m, &m, x, y, &x, &y);
2863  if (!(mflags&P_OUT_OF_MAP) && mflags&P_IS_ALIVE) {
2864  FOR_MAP_PREPARE(m, x, y, tmp)
2865  plyr = tmp;
2866  if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
2867  break;
2868  FOR_MAP_FINISH();
2869  }
2870 
2871  /* If we did not find a player in the specified direction, transfer
2872  * to anyone on top of us. This is used for the rune of transference mostly.
2873  */
2874  if (plyr == NULL)
2875  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp)
2876  plyr = tmp;
2877  if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
2878  break;
2879  FOR_MAP_FINISH();
2880 
2881  if (!plyr) {
2883  "There is no one there.");
2884  return 0;
2885  }
2886 
2887  /* give sp */
2888  if (spell->stats.dam > 0) {
2889  plyr->stats.sp += spell->stats.dam+SP_level_dam_adjust(caster, spell);
2890  charge_mana_effect(plyr, caster_level(caster, spell));
2891  return 1;
2892  /* suck sp away. Can't suck sp from yourself */
2893  } else if (op != plyr) {
2894  /* old dragin magic used floats. easier to just use ints and divide by 100 */
2895 
2896  int rate = -spell->stats.dam+SP_level_dam_adjust(caster, spell), sucked;
2897 
2898  if (rate > 95)
2899  rate = 95;
2900 
2901  sucked = (plyr->stats.sp*rate)/100;
2902  plyr->stats.sp -= sucked;
2903  if (QUERY_FLAG(op, FLAG_ALIVE)) {
2904  /* Player doesn't get full credit */
2905  sucked = (sucked*rate)/100;
2906  op->stats.sp += sucked;
2907  if (sucked > 0) {
2908  charge_mana_effect(op, caster_level(caster, spell));
2909  }
2910  }
2911  return 1;
2912  }
2913  return 0;
2914 }
2915 
2925 void counterspell(object *op, int dir) {
2926  object *head;
2927  int mflags;
2928  mapstruct *m;
2929  int16_t sx, sy;
2930 
2931  sx = op->x+freearr_x[dir];
2932  sy = op->y+freearr_y[dir];
2933  m = op->map;
2934  mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
2935  if (mflags&P_OUT_OF_MAP)
2936  return;
2937 
2938  FOR_MAP_PREPARE(m, sx, sy, tmp) {
2939  object *owner;
2940 
2941  /* Need to look at the head object - otherwise, if tmp
2942  * points to a monster, we don't have all the necessary
2943  * info for it.
2944  */
2945  head = HEAD(tmp);
2946 
2947  /* don't attack our own spells */
2948  owner = object_get_owner(tmp);
2949  if (owner != NULL && owner == object_get_owner(op))
2950  continue;
2951 
2952  /* Basically, if the object is magical and not counterspell,
2953  * we will more or less remove the object. Don't counterspell
2954  * monsters either.
2955  */
2956 
2957  if (head->attacktype&AT_MAGIC
2958  && !(head->attacktype&AT_COUNTERSPELL)
2959  && !QUERY_FLAG(head, FLAG_MONSTER)
2960  && (op->level > head->level)) {
2961  object_remove(head);
2962  object_free(head, 0);
2963  } else switch (head->type) {
2964  case SPELL_EFFECT:
2965  if ((op->level > head->level) && !op->stats.food && !op->speed_left) {
2966  object_remove(head);
2967  object_free(head, 0);
2968  }
2969  break;
2970 
2971  /* I really don't get this rune code that much - that
2972  * random chance seems really low.
2973  */
2974  case RUNE:
2975  if (rndm(0, 149) == 0) {
2976  head->stats.hp--; /* weaken the rune */
2977  if (!head->stats.hp) {
2978  object_remove(head);
2979  object_free(head, 0);
2980  }
2981  }
2982  break;
2983  }
2984  } FOR_MAP_FINISH();
2985 }
2986 
3001 int cast_consecrate(object *op, object *caster, object *spell) {
3002  char buf[MAX_BUF];
3003  const object *god = find_god(determine_god(op));
3004 
3005  if (!god) {
3007  "You can't consecrate anything if you don't worship a god!");
3008  return 0;
3009  }
3010 
3011  FOR_BELOW_PREPARE(op, tmp) {
3012  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
3013  break;
3014  if (tmp->type == HOLY_ALTAR) {
3015  if (tmp->level > caster_level(caster, spell)) {
3017  "You are not powerful enough to reconsecrate the %s",
3018  tmp->name);
3019  return 0;
3020  } else {
3021  /* If we got here, we are consecrating an altar */
3022  object *new_altar;
3023  size_t letter;
3024  archetype *altar_arch;
3025 
3026  snprintf(buf, MAX_BUF, "altar_");
3027  letter = strlen(buf);
3028  strncpy(buf+letter, god->name, MAX_BUF-letter);
3029  for (; letter < strlen(buf); letter++)
3030  buf[letter] = tolower(buf[letter]);
3031  altar_arch = try_find_archetype(buf);
3032  if (!altar_arch) {
3034  "You fail to consecrate the altar.");
3035  LOG(llevError, "cast_consecrate: can't find altar %s for god %s\n", buf, god->name);
3036  return 0;
3037  }
3038  new_altar = arch_to_object(altar_arch);
3039  new_altar->level = tmp->level;
3040  if (QUERY_FLAG(tmp, FLAG_IS_BUILDABLE))
3041  SET_FLAG(new_altar, FLAG_IS_BUILDABLE);
3042  object_insert_in_map_at(new_altar, tmp->map, tmp, INS_BELOW_ORIGINATOR, tmp->x, tmp->y);
3043  object_remove(tmp);
3045  "You consecrated the altar to %s!",
3046  god->name);
3047  return 1;
3048  }
3049  }
3050  } FOR_BELOW_FINISH();
3052  "You are not standing over an altar!");
3053  return 0;
3054 }
3055 
3079 int animate_weapon(object *op, object *caster, object *spell, int dir) {
3080  object *weapon, *tmp;
3081  char buf[MAX_BUF];
3082  int a, i;
3083  int16_t x, y;
3084  mapstruct *m;
3085  materialtype_t *mt;
3086 
3087  if (!spell->other_arch) {
3089  "Oops, program error!");
3090  LOG(llevError, "animate_weapon failed: spell %s missing other_arch!\n", spell->name);
3091  return 0;
3092  }
3093 
3094  /* exit if it's not a player using this spell. */
3095  if (op->type != PLAYER)
3096  return 0;
3097 
3098  /* if player already has a golem, abort */
3099  if (op->contr->ranges[range_golem] != NULL && op->contr->golem_count == op->contr->ranges[range_golem]->count) {
3100  pets_control_golem(op->contr->ranges[range_golem], dir);
3101  return 0;
3102  }
3103 
3104  /* if no direction specified, pick one */
3105  if (!dir) {
3106  dir = object_find_free_spot(NULL, op->map, op->x, op->y, 1, 9);
3107  if ( dir == -1 ) {
3109  "There is something in the way.");
3110  return 0;
3111  }
3112  }
3113 
3114  m = op->map;
3115  x = op->x+freearr_x[dir];
3116  y = op->y+freearr_y[dir];
3117 
3118  /* if there's no place to put the golem, abort */
3119  if ((dir == -1)
3120  || (get_map_flags(m, &m, x, y, &x, &y)&P_OUT_OF_MAP)
3121  || ((spell->other_arch->clone.move_type&GET_MAP_MOVE_BLOCK(m, x, y)) == spell->other_arch->clone.move_type)) {
3123  "There is something in the way.");
3124  return 0;
3125  }
3126 
3127  /* Use the weapon marked by the player. */
3128  weapon = find_marked_object(op);
3129 
3130  if (!weapon) {
3132  "You must mark a weapon to use with this spell!");
3133  return 0;
3134  }
3135  if (spell->race && strcmp(weapon->arch->name, spell->race)) {
3137  "The spell fails to transform your weapon.");
3138  return 0;
3139  }
3140  if (weapon->type != WEAPON) {
3142  "You need to mark a weapon to animate it.");
3143  return 0;
3144  }
3145  if (QUERY_FLAG(weapon, FLAG_UNPAID)) {
3147  "You need to pay for the weapon to animate it.");
3148  return 0;
3149  }
3150  if (QUERY_FLAG(weapon, FLAG_APPLIED)) {
3151  char wn[MAX_BUF];
3152 
3153  query_name(weapon, wn, MAX_BUF);
3155  "You need to unequip %s before using it in this spell",
3156  wn);
3157  return 0;
3158  }
3159 
3160  if (weapon->nrof > 1) {
3161  tmp = object_split(weapon, 1, NULL, 0);
3162  esrv_update_item(UPD_NROF, op, weapon);
3163  weapon = tmp;
3164  }
3165 
3166  /* create the golem object */
3167  tmp = arch_to_object(spell->other_arch);
3168 
3169  /* if animated by a player, give the player control of the golem */
3170  CLEAR_FLAG(tmp, FLAG_MONSTER);
3171  SET_FLAG(tmp, FLAG_FRIENDLY);
3172  tmp->stats.exp = 0;
3173  add_friendly_object(tmp);
3174  tmp->type = GOLEM;
3175  object_set_owner(tmp, op);
3176  set_spell_skill(op, caster, spell, tmp);
3177  op->contr->ranges[range_golem] = tmp;
3178  op->contr->shoottype = range_golem;
3179  op->contr->golem_count = tmp->count;
3180 
3181  /* Give the weapon to the golem now. A bit of a hack to check the
3182  * removed flag - it should only be set if object_split() was
3183  * used above.
3184  */
3185  if (!QUERY_FLAG(weapon, FLAG_REMOVED))
3186  object_remove(weapon);
3187  object_insert_in_ob(weapon, tmp);
3188 
3189  /* To do everything necessary to let a golem use the weapon is a pain,
3190  * so instead, just set it as equipped (otherwise, we need to update
3191  * body_info, skills, etc)
3192  */
3193  SET_FLAG(tmp, FLAG_USE_WEAPON);
3194  SET_FLAG(weapon, FLAG_APPLIED);
3195  fix_object(tmp);
3196 
3197  /* There used to be 'odd' code that basically seemed to take the absolute
3198  * value of the weapon->magic an use that. IMO, that doesn't make sense -
3199  * if you're using a crappy weapon, it shouldn't be as good.
3200  */
3201 
3202  /* modify weapon's animated wc */
3203  tmp->stats.wc = tmp->stats.wc
3204  -SP_level_range_adjust(caster, spell)
3205  -5*weapon->stats.Dex
3206  -2*weapon->stats.Str
3207  -weapon->magic;
3208  if (tmp->stats.wc < -127)
3209  tmp->stats.wc = -127;
3210 
3211  /* Modify hit points for weapon */
3212  tmp->stats.maxhp = tmp->stats.maxhp
3213  +spell->duration
3214  +SP_level_duration_adjust(caster, spell)
3215  +8*weapon->magic
3216  +12*weapon->stats.Con;
3217  if (tmp->stats.maxhp < 0)
3218  tmp->stats.maxhp = 10;
3219  tmp->stats.hp = tmp->stats.maxhp;
3220 
3221  /* Modify weapon's damage */
3222  tmp->stats.dam = spell->stats.dam
3223  +SP_level_dam_adjust(caster, spell)
3224  +weapon->stats.dam
3225  +weapon->magic
3226  +5*weapon->stats.Str;
3227  if (tmp->stats.dam < 0)
3228  tmp->stats.dam = 127;
3229 
3230  /* attacktype */
3231  if (!tmp->attacktype)
3232  tmp->attacktype = AT_PHYSICAL;
3233 
3234  mt = NULL;
3235  if (op->materialname != NULL)
3236  mt = name_to_material(op->materialname);
3237  if (mt != NULL) {
3238  for (i = 0; i < NROFATTACKS; i++)
3239  tmp->resist[i] = 50-(mt->save[i]*5);
3240  a = mt->save[0];
3241  } else {
3242  for (i = 0; i < NROFATTACKS; i++)
3243  tmp->resist[i] = 5;
3244  a = 10;
3245  }
3246  /* Set weapon's immunity */
3247  tmp->resist[ATNR_CONFUSION] = 100;
3248  tmp->resist[ATNR_POISON] = 100;
3249  tmp->resist[ATNR_SLOW] = 100;
3250  tmp->resist[ATNR_PARALYZE] = 100;
3251  tmp->resist[ATNR_TURN_UNDEAD] = 100;
3252  tmp->resist[ATNR_FEAR] = 100;
3253  tmp->resist[ATNR_DEPLETE] = 100;
3254  tmp->resist[ATNR_DEATH] = 100;
3255  tmp->resist[ATNR_BLIND] = 100;
3256 
3257  /* Improve weapon's armour value according to best save vs. physical of its material */
3258 
3259  if (a > 14)
3260  a = 14;
3261  tmp->resist[ATNR_PHYSICAL] = 100-(int)((100.0-(float)tmp->resist[ATNR_PHYSICAL])/(30.0-2.0*a));
3262 
3263  /* Determine golem's speed */
3264  tmp->speed = 0.4+0.1*SP_level_range_adjust(caster, spell);
3265 
3266  if (tmp->speed > 3.33)
3267  tmp->speed = 3.33;
3268 
3269  if (!spell->race) {
3270  snprintf(buf, sizeof(buf), "animated %s", weapon->name);
3271  if (tmp->name)
3272  free_string(tmp->name);
3273  tmp->name = add_string(buf);
3274 
3275  tmp->face = weapon->face;
3276  tmp->animation = weapon->animation;
3277  tmp->anim_speed = weapon->anim_speed;
3278  tmp->last_anim = weapon->last_anim;
3279  tmp->state = weapon->state;
3280  if (QUERY_FLAG(weapon, FLAG_ANIMATE)) {
3281  SET_FLAG(tmp, FLAG_ANIMATE);
3282  } else {
3283  CLEAR_FLAG(tmp, FLAG_ANIMATE);
3284  }
3285  object_update_speed(tmp);
3286  }
3287 
3288  /* make experience increase in proportion to the strength of the summoned creature. */
3289  tmp->stats.exp *= 1+(MAX(spell->stats.maxgrace, spell->stats.sp)/caster_level(caster, spell));
3290 
3291  tmp->speed_left = -1;
3292  tmp->direction = dir;
3293  object_insert_in_map_at(tmp, m, op, 0, x, y);
3294  return 1;
3295 }
3296 
3311 int cast_change_map_lightlevel(object *op, object *caster, object *spell) {
3312  int success;
3313 
3314  if (!op->map)
3315  return 0; /* shouldnt happen */
3316 
3317  success = change_map_light(op->map, spell->stats.dam);
3318  if (!success) {
3319  if (spell->stats.dam < 0)
3321  "It can be no brighter here.");
3322  else
3324  "It can be no darker here.");
3325  }
3326  return success;
3327 }
3328 
3343 int create_aura(object *op, object *caster, object *spell) {
3344  int refresh = 0, i;
3345  object *new_aura;
3346 
3347  new_aura = arch_present_in_ob(spell->other_arch, op);
3348  if (new_aura)
3349  refresh = 1;
3350  else
3351  new_aura = arch_to_object(spell->other_arch);
3352 
3353  new_aura->duration = spell->duration+10*SP_level_duration_adjust(caster, spell);
3354  if (op->type == PLAYER)
3355  store_spell_expiry(new_aura);
3356 
3357  new_aura->stats.dam = spell->stats.dam+SP_level_dam_adjust(caster, spell);
3358 
3359  object_set_owner(new_aura, op);
3360  set_spell_skill(op, caster, spell, new_aura);
3361  new_aura->attacktype = spell->attacktype;
3362 
3363  new_aura->level = caster_level(caster, spell);
3364 
3365  /* Code below is so that auras can also provide resistances. For
3366  * example, fire shield both does damage to nearby enemies and also
3367  * provides some protection to fire. We need to use a different
3368  * FORCE object for this, as putting it in with the aura object
3369  * just puts too many meanings into that one object. Because
3370  * the duration of this force object is the same, we don't need
3371  * to set up spell expiry on it - this second object is really
3372  * an internal mechanic that should be invisible to the player.
3373  */
3374  for (i = 0; i < NROFATTACKS; i++) {
3375  if (spell->resist[i]) {
3376  int refresh1=1;
3377  object *force;
3378 
3379  force = object_present_in_ob_by_name(FORCE, spell->name, op);
3380  if (!force) {
3382  force->subtype = FORCE_CHANGE_ABILITY;
3383  free_string(force->name);
3384  force->name = add_refcount(spell->name);
3385  free_string(force->name_pl);
3386  force->name_pl = add_refcount(spell->name);
3387  refresh1=0;
3388  }
3389  force->duration = new_aura->duration;
3390  force->speed = new_aura->speed;
3391  memcpy(&force->resist, spell->resist, sizeof(spell->resist));
3392  SET_FLAG(force, FLAG_APPLIED);
3393 
3394  if (!refresh1)
3395  object_insert_in_ob(force, op);
3396  change_abil(op, new_aura);
3397  fix_object(op);
3398  break;
3399  }
3400  }
3401 
3402  if (refresh)
3404  "You recast the spell while in effect.");
3405  else
3406  object_insert_in_ob(new_aura, op);
3407  return 1;
3408 }
3409 
3425 int write_mark(object *op, object *spell, const char *msg) {
3426  char rune[HUGE_BUF];
3427  object *tmp;
3428 
3429  if (!msg || msg[0] == 0) {
3431  "Write what?");
3432  return 0;
3433  }
3434 
3435  if (strcasestr_local(msg, "endmsg")) {
3437  "Trying to cheat are we?");
3438  LOG(llevInfo, "write_rune: player %s tried to write bogus rune %s\n", op->name, msg);
3439  return 0;
3440  }
3441 
3442  if (!spell->other_arch)
3443  return 0;
3444  tmp = arch_to_object(spell->other_arch);
3445  strncpy(rune, msg, HUGE_BUF-2);
3446  rune[HUGE_BUF-2] = 0;
3447  strcat(rune, "\n");
3448  tmp->race = add_string(op->name); /*Save the owner of the rune*/
3449  object_set_msg(tmp, rune);
3450  object_insert_in_map_at(tmp, op->map, op, INS_BELOW_ORIGINATOR, op->x, op->y);
3451  return 1;
3452 }
static object * town_portal_find_force(object *op, object *spell)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:313
#define FLAG_KNOWN_BLESSED
Definition: define.h:379
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:219
#define FLAG_NO_DROP
Definition: define.h:289
Definition: player.h:92
void cast_magic_storm(object *op, object *tmp, int lvl)
Definition: spell_effect.c:46
#define FLAG_SEE_IN_DARK
Definition: define.h:338
int apply_manual(object *op, object *tmp, int aflag)
Definition: apply.c:597
const char * determine_god(object *op)
Definition: gods.c:106
#define FLAG_DAMNED
Definition: define.h:318
#define FLAG_IS_FLOOR
Definition: define.h:303
#define FLAG_UNPAID
Definition: define.h:236
#define MOVE_WALK
Definition: define.h:407
uint8_t create_home_portals
Definition: global.h:311
#define FORCE_CHANGE_ABILITY
Definition: spells.h:145
int cast_bless(object *op, object *caster, object *spell_ob, int dir)
#define MSG_TYPE_ITEM
Definition: newclient.h:388
#define AT_COUNTERSPELL
Definition: attack.h:95
void object_free(object *ob, int flags)
Definition: object.c:1348
materialtype_t * name_to_material(const char *name)
Definition: utils.c:248
int is_magical(const object *op)
Definition: item.c:1195
#define ATNR_TURN_UNDEAD
Definition: attack.h:62
int cast_detection(object *op, object *caster, object *spell)
#define FOR_OB_AND_ABOVE_PREPARE(op_)
Definition: define.h:776
int caster_level(const object *caster, const object *spell)
Definition: spell_util.c:233
void esrv_send_item(object *pl, object *op)
Definition: main.c:337
#define SET_FLAG(xyz, p)
Definition: define.h:223
sstring add_refcount(sstring str)
Definition: shstr.c:210
static archetype * food_choice
Definition: spell_effect.c:605
const artifactlist * find_artifactlist(int type)
Definition: artifact.c:644
object * object_find_by_type_applied(const object *who, int type)
Definition: object.c:3873
#define FABS(x)
Definition: define.h:22
int cure_disease(object *sufferer, object *caster, sstring skill)
Definition: disease.c:685
int cast_create_food(object *op, object *caster, object *spell_ob, int dir, const char *stringarg)
Definition: spell_effect.c:639
StringBuffer * buf
Definition: readable.c:1591
#define MSG_TYPE_ITEM_INFO
Definition: newclient.h:641
static void place_alchemy_objects(object *op, mapstruct *m, int small_nuggets, int large_nuggets, int x, int y)
int write_mark(object *op, object *spell, const char *msg)
#define NDI_ORANGE
Definition: newclient.h:225
#define FLAG_FRIENDLY
Definition: define.h:246
#define P_NO_MAGIC
Definition: map.h:227
struct artifactstruct * items
Definition: artifact.h:30
object * mon
Definition: comet_perf.c:74
#define ATNR_DEPLETE
Definition: attack.h:65
#define MSG_TYPE_SPELL
Definition: newclient.h:387
void archetypes_for_each(arch_op op)
Definition: assets.cpp:302
int8_t save[NROFATTACKS]
Definition: material.h:37
#define FLAG_NO_FIX_PLAYER
Definition: define.h:277
#define EXPLODING_FIREBALL
Definition: spells.h:174
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.c:1796
#define MSG_TYPE_SPELL_FAILURE
Definition: newclient.h:628
void free_string(sstring str)
Definition: shstr.c:280
#define HUGE_BUF
Definition: define.h:37
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.c:340
int alchemy(object *op, object *caster, object *spell_ob)
void examine_monster(object *op, object *tmp, int level)
Definition: c_object.c:1603
int cast_invisible(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:811
void pick_up(object *op, object *alt)
Definition: c_object.c:509
int cast_word_of_recall(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:923
int magic_wall(object *op, object *caster, int dir, object *spell_ob)
#define ATNR_SLOW
Definition: attack.h:60
short freearr_x[SIZEOFFREE]
Definition: object.c:65
#define PREFER_LOW
Definition: define.h:601
int cast_item_curse_or_curse(object *op, object *caster, object *spell_ob)
#define FLAG_USE_WEAPON
Definition: define.h:297
int SP_level_dam_adjust(const object *caster, const object *spob)
Definition: spell_util.c:326
#define FLAG_BLESSED
Definition: define.h:378
int cast_earth_to_dust(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:872
int remove_curse(object *op, object *caster, object *spell)
object * arch_present_in_ob(const archetype *at, const object *op)
Definition: object.c:2954
int8_t get_attr_value(const living *stats, int attr)
Definition: living.c:314
void remove_friendly_object(object *op)
Definition: friend.c:56
#define MAX(x, y)
Definition: compat.h:20
void object_update(object *op, int action)
Definition: object.c:1190
method_ret ob_apply(object *op, object *applier, int aflags)
Definition: ob_methods.c:44
#define FLAG_TEAR_DOWN
Definition: define.h:279
#define AT_BLIND
Definition: attack.h:98
const object * find_god(const char *name)
Definition: gods.c:80
#define NDI_BLACK
Definition: newclient.h:221
#define PETMOVE
Definition: define.h:518
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:308
static void food_each(archetype *arch)
Definition: spell_effect.c:607
#define ATNR_CONFUSION
Definition: attack.h:54
#define MSG_TYPE_VICTIM_SPELL
Definition: newclient.h:651
#define SP_WORD_OF_RECALL
Definition: spells.h:92
#define FOR_OB_AND_BELOW_FINISH()
Definition: define.h:791
#define MIN(x, y)
Definition: compat.h:17
archetype * try_find_archetype(const char *name)
Definition: assets.cpp:255
int change_map_light(mapstruct *m, int change)
Definition: map.c:2001
#define FLAG_REMOVED
Definition: define.h:232
int cast_cone(object *op, object *caster, int dir, object *spell)
Definition: spell_attack.c:297
short freearr_y[SIZEOFFREE]
Definition: object.c:71
#define FLAG_KNOWN_MAGICAL
Definition: define.h:320
object * active_objects
Definition: object.c:62
#define SOUND_TYPE_ITEM
Definition: newclient.h:310
#define NDI_NAVY
Definition: newclient.h:223
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:252
archetype * find_archetype_by_object_type_name(int type, const char *name)
Definition: arch.cpp:68
#define FLAG_IS_USED_UP
Definition: define.h:260
#define strcasestr_local
Definition: compat.h:24
void pets_control_golem(object *op, int dir)
Definition: pets.c:627
void polymorph(object *op, object *who, int level)
Definition: spell_effect.c:380
int rndm(int min, int max)
Definition: utils.c:162
void map_newmap_cmd(socket_struct *ns)
Definition: request.c:618
int probe(object *op, object *caster, object *spell_ob, int dir, int level)
Definition: spell_effect.c:707
#define FLAG_UNDEAD
Definition: define.h:270
void object_set_owner(object *op, object *owner)
Definition: object.c:604
#define MSG_TYPE_SPELL_TARGET
Definition: newclient.h:633
int change_abil(object *op, object *tmp)
Definition: living.c:395
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1849
static void polymorph_item(object *who, object *op, int level)
Definition: spell_effect.c:279
int cast_heal(object *op, object *caster, object *spell, int dir)
#define FLAG_ALIVE
Definition: define.h:230
void confuse_living(object *op, object *hitter, int dam)
Definition: attack.c:2250
int recharge(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:81
int is_identified(const object *op)
Definition: item.c:1316
#define MSG_TYPE_VICTIM
Definition: newclient.h:392
object * object_new(void)
Definition: object.c:1011
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.c:95
#define FOR_OB_AND_ABOVE_FINISH()
Definition: define.h:780
#define AT_DISEASE
Definition: attack.h:102
int cast_transfer(object *op, object *caster, object *spell, int dir)
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2602
#define MSG_TYPE_SPELL_SUCCESS
Definition: newclient.h:630
#define ATNR_PARALYZE
Definition: attack.h:61
#define MSG_TYPE_SPELL_HEAL
Definition: newclient.h:626
signed short int16_t
Definition: win32.h:160
object * arch_to_object(archetype *at)
Definition: arch.cpp:232
#define MOVE_FLY_LOW
Definition: define.h:408
object * find_target_for_friendly_spell(object *op, int dir)
Definition: spell_util.c:852
void update_all_los(const mapstruct *map, int x, int y)
Definition: los.c:536
object * create_archetype(const char *name)
Definition: arch.cpp:281
const char *const statname[NUM_STATS]
Definition: living.c:184
void monster_check_apply_all(object *monster)
Definition: monster.c:1827
int is_dragon_pl(const object *op)
Definition: player.c:114
#define ATNR_DEATH
Definition: attack.h:66
#define snprintf
Definition: win32.h:46
static void charge_mana_effect(object *victim, int caster_level)
#define SP_WONDER
Definition: spells.h:83
int cast_create_obj(object *op, object *new_op, int dir)
Definition: spell_util.c:533
int strcasecmp(const char *s1, const char *s2)
#define FLAG_IDENTIFIED
Definition: define.h:261
#define FOR_INV_FINISH()
Definition: define.h:714
#define MSG_TYPE_SPELL_PERCEIVE_SELF
Definition: newclient.h:632
int create_aura(object *op, object *caster, object *spell)
int SP_level_duration_adjust(const object *caster, const object *spob)
Definition: spell_util.c:351
#define ATNR_BLIND
Definition: attack.h:71
#define MSG_TYPE_SPELL_ERROR
Definition: newclient.h:631
void add_friendly_object(object *op)
Definition: friend.c:30
#define FLAG_BLOCKSVIEW
Definition: define.h:269
int dimension_door(object *op, object *caster, object *spob, int dir)
int cast_identify(object *op, object *caster, object *spell)
int cast_wonder(object *op, object *caster, int dir, object *spell_ob)
Definition: spell_effect.c:985
void spell_effect(object *spob, int x, int y, mapstruct *map, object *originator)
Definition: spell_util.c:183
#define ATNR_FEAR
Definition: attack.h:63
int cast_change_map_lightlevel(object *op, object *caster, object *spell)
int is_true_undead(object *op)
Definition: player.c:3930
#define EXIT_PATH(xyz)
Definition: define.h:454
uint64_t price_base(const object *obj)
Definition: shop.c:75
#define SMALL_NUGGET
EXTERN const char *const change_resist_msg[NROFATTACKS]
Definition: attack.h:135
#define ATNR_MAGIC
Definition: attack.h:50
#define OB_TYPE_MOVE_BLOCK(ob1, type)
Definition: define.h:447
#define UPD_FLAGS
Definition: newclient.h:290
#define FLAG_IS_CAULDRON
Definition: define.h:339
#define SIZEOFFREE
Definition: define.h:154
#define P_OUT_OF_MAP
Definition: map.h:251
#define GET_MAP_MOVE_BLOCK(M, X, Y)
Definition: map.h:192
#define EXIT_X(xyz)
Definition: define.h:456
static int town_portal_destroy_existing(object *op, object *spell)
archetype * get_next_archetype(archetype *current)
Definition: assets.cpp:247
#define FLAG_XRAYS
Definition: define.h:301
object * find_marked_object(object *op)
Definition: c_object.c:1509
#define FREE_AND_CLEAR_STR(xyz)
Definition: global.h:198
#define ATNR_PHYSICAL
Definition: attack.h:49
static void polymorph_melt(object *who, object *op)
Definition: spell_effect.c:251
long last_reset_time
Definition: map.h:366
static void alchemy_object(float value_adj, object *obj, int *small_nuggets, int *large_nuggets, int *weight)
#define ATNR_POISON
Definition: attack.h:59
#define AT_PHYSICAL
Definition: attack.h:76
unsigned __int64 uint64_t
Definition: win32.h:167
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
int animate_weapon(object *op, object *caster, object *spell, int dir)
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
#define FLAG_WIZ
Definition: define.h:231
void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags)
Definition: treasure.c:887
#define EXIT_Y(xyz)
Definition: define.h:457
#define MAX_BUF
Definition: define.h:35
void give_artifact_abilities(object *op, const object *artifact)
Definition: artifact.c:203
int cast_change_ability(object *op, object *caster, object *spell_ob, int dir, int silent)
static const char *const no_gain_msgs[NUM_STATS]
#define tolower(C)
Definition: c_new.c:30
uint16_t difficulty
Definition: map.h:343
object * object_create_arch(archetype *at)
Definition: arch.cpp:301
#define FOR_MAP_FINISH()
Definition: define.h:767
#define FLAG_KNOWN_CURSED
Definition: define.h:321
#define FLAG_CURSED
Definition: define.h:317
unsigned int uint32_t
Definition: win32.h:162
int perceive_self(object *op)
char * ob_describe(const object *op, const object *observer, int use_media_tags, char *buf, size_t size)
Definition: ob_methods.c:91
object * check_inv_recursive(object *op, const object *trig)
Definition: button.c:782
void store_spell_expiry(object *spell)
Definition: spell_util.c:2017
object * object_find_by_type_subtype(const object *who, int type, int subtype)
Definition: object.c:4091
#define AT_POISON
Definition: attack.h:86
#define FLAG_ANIMATE
Definition: define.h:242
#define PREFER_HIGH
Definition: define.h:600
#define FLAG_GENERATOR
Definition: define.h:248
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.c:2382
StringBuffer * describe_item(const object *op, const object *owner, int use_media_tags, StringBuffer *buf)
Definition: item.c:935
int cast_consecrate(object *op, object *caster, object *spell)
#define FREE_AND_COPY(sv, nv)
Definition: global.h:204
#define UPD_NROF
Definition: newclient.h:296
signed char int8_t
Definition: win32.h:158
int cast_polymorph(object *op, object *caster, object *spell_ob, int dir)
Definition: spell_effect.c:434
int SP_level_range_adjust(const object *caster, const object *spob)
Definition: spell_util.c:377
#define MAP_PLAYER_UNIQUE
Definition: map.h:97
const char * localdir
Definition: global.h:246
#define FLAG_WIZCAST
Definition: define.h:290
void set_spell_skill(object *op, object *caster, object *spob, object *dest)
Definition: spell_util.c:94
#define ATNR_GODPOWER
Definition: attack.h:69
#define FLAG_IS_BUILDABLE
Definition: define.h:376
struct Settings settings
Definition: init.c:39
void object_set_enemy(object *op, object *enemy)
Definition: object.c:679
static int food_value_choice
Definition: spell_effect.c:606
#define FLAG_APPLIED
Definition: define.h:235
#define NROFATTACKS
Definition: attack.h:17
void query_short_name(const object *op, char *buf, size_t size)
Definition: item.c:508
#define UPD_NAME
Definition: newclient.h:293
#define FLAG_MAKE_INVIS
Definition: define.h:329
#define NDI_GREY
Definition: newclient.h:232
#define FOR_OB_AND_BELOW_PREPARE(op_)
Definition: define.h:787
#define FLAG_STARTEQUIP
Definition: define.h:268
#define FORCE_NAME
Definition: spells.h:169
int64_t * levels
Definition: exp.c:26
#define AT_MAGIC
Definition: attack.h:77
sstring add_string(const char *str)
Definition: shstr.c:124
object * identify(object *op)
Definition: item.c:1386
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
static const int32_t MAX_FOOD
Definition: define.h:476
#define GET_MAP_OB(M, X, Y)
Definition: map.h:172
#define FLAG_MONSTER
Definition: define.h:245
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.c:824
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.c:310
#define NDI_UNIQUE
Definition: newclient.h:245
void counterspell(object *op, int dir)
void player_update_bg_music(object *player)
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
int makes_invisible_to(object *pl, object *mon)
Definition: spell_effect.c:764
int did_make_save(const object *op, int level, int bonus)
Definition: living.c:2280
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:760
int cast_create_missile(object *op, object *caster, object *spell, int dir, const char *stringarg)
Definition: spell_effect.c:502
void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action)
Definition: sounds.c:107
#define P_BLOCKSVIEW
Definition: map.h:226
void object_set_msg(object *op, const char *msg)
Definition: object.c:4570
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
Definition: object.c:3291
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:583
object * item
Definition: artifact.h:15
#define LARGE_NUGGET
#define FOR_BELOW_PREPARE(op_, it_)
Definition: define.h:741
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.c:284
object * map_find_by_archetype(mapstruct *m, int x, int y, const archetype *at)
Definition: object.c:2850
Definition: map.h:325
#define P_IS_ALIVE
Definition: map.h:237
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.c:42
#define AT_CONFUSION
Definition: attack.h:81
#define FLAG_NO_PICK
Definition: define.h:239
object * object_find_by_type_and_arch_name(const object *who, int type, const char *name)
Definition: object.c:4067
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
Definition: attack.c:1847
void fix_object(object *op)
Definition: living.c:1124
void object_update_speed(object *op)
Definition: object.c:1086
object * object_get_owner(object *op)
Definition: object.c:568
static void polymorph_living(object *op, int level)
Definition: spell_effect.c:159
int level
Definition: readable.c:1589
int cast_create_town_portal(object *op, object *caster, object *spell, int dir)
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
#define FOR_BELOW_FINISH()
Definition: define.h:748
#define HAS_RANDOM_ITEMS(op)
Definition: define.h:183
object * object_present_in_ob_by_name(int type, const char *str, const object *op)
Definition: object.c:2935
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:707
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Definition: spell_util.c:1459
void object_remove(object *op)
Definition: object.c:1588
struct artifactstruct * next
Definition: artifact.h:18
int atnr_is_dragon_enabled(int attacknr)
Definition: player.c:95