Crossfire Server, Trunk  R21466
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 
45 void cast_magic_storm(object *op, object *tmp, int lvl) {
46  if (!tmp)
47  return; /* error */
48  tmp->level = op->level;
49  tmp->range += lvl/5; /* increase the area of destruction */
50  tmp->duration += lvl/5;
51 
52  /* Put a cap on duration for this - if the player fails in their
53  * apartment, don't want it to go on so long that it kills them
54  * multiple times. Also, damage already increases with level,
55  * so don't really need to increase the duration as much either.
56  */
57  if (tmp->duration >= 40)
58  tmp->duration = 40;
59  tmp->stats.dam = lvl; /* nasty recoils! */
60  tmp->stats.maxhp = tmp->count; /* tract single parent */
61  if (tmp->stats.maxhp == 0)
62  tmp->stats.maxhp = 1;
63  object_insert_in_map_at(tmp, op->map, op, 0, op->x, op->y);
64 }
65 
80 int recharge(object *op, object *caster, object *spell_ob) {
81  object *wand, *tmp;
82  int ncharges;
83  char name[MAX_BUF];
84 
85  wand = find_marked_object(op);
86  if (wand == NULL || wand->type != WAND) {
88  "You need to mark the wand you want to recharge.");
89  return 0;
90  }
91  if (!(random_roll(0, 3, op, PREFER_HIGH))) {
92  query_name(wand, name, MAX_BUF);
94  "The %s vibrates violently, then explodes!",
95  name);
96  play_sound_map(SOUND_TYPE_ITEM, wand, 0, "explode");
97  object_remove(wand);
98  object_free(wand, 0);
99  tmp = create_archetype("fireball");
100  tmp->stats.dam = (spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob))/10;
101  if (!tmp->stats.dam)
102  tmp->stats.dam = 1;
103  tmp->stats.hp = tmp->stats.dam/2;
104  if (tmp->stats.hp < 2)
105  tmp->stats.hp = 2;
106  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
107  return 1;
108  }
109 
110  ncharges = (spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob));
111  if (wand->inv && wand->inv->level)
112  ncharges /= wand->inv->level;
113  else {
114  query_name(wand, name, MAX_BUF);
116  "Your %s is broken.",
117  name);
118  return 0;
119  }
120  if (!ncharges)
121  ncharges = 1;
122 
123  wand->stats.food += ncharges;
124  query_name(wand, name, MAX_BUF);
126  "The %s glows with power.",
127  name);
128 
129  if (wand->arch && QUERY_FLAG(&wand->arch->clone, FLAG_ANIMATE)) {
130  SET_FLAG(wand, FLAG_ANIMATE);
131  wand->speed = wand->arch->clone.speed;
132  object_update_speed(wand);
133  }
134  return 1;
135 }
136 
137 /******************************************************************************
138  * Start of polymorph related functions.
139  *
140  * Changed around for 0.94.3 - it will now look through and use all the
141  * possible choices for objects/monsters (before it was the first 80 -
142  * arbitrary hardcoded limit in this file.) Doing this will be a bit
143  * slower however - while before, it traversed the archetypes once and
144  * stored them into an array, it will now potentially traverse it
145  * an average of 1.5 times. This is probably more costly on the polymorph
146  * item function, since it is possible a couple lookups might be needed before
147  * an item of proper value is generated.
148  */
149 
158 static void polymorph_living(object *op, int level) {
159  archetype *at;
160  int x = op->x, y = op->y, numat = 0, choice, friendly;
161  mapstruct *map = op->map;
162  object *owner;
163 
164  op = HEAD(op);
165 
166  /* High level creatures are immune, as are creatures immune to magic. Otherwise,
167  * give the creature a saving throw.
168  */
169  if (op->level >= level*2
170  || did_make_save(op, op->level, op->resist[ATNR_MAGIC]/10)
171  || (op->resist[ATNR_MAGIC] == 100))
172  return;
173 
174  object_remove(op);
175 
176  /* First, count up the number of legal matches */
177  for (at = first_archetype; at != NULL; at = at->next)
178  if ((QUERY_FLAG((&at->clone), FLAG_MONSTER) == QUERY_FLAG(op, FLAG_MONSTER))
179  && (object_find_free_spot(&at->clone, map, x, y, 0, SIZEOFFREE) != -1)) {
180  numat++;
181  }
182  if (!numat) {
183  object_insert_in_map_at(op, map, NULL, 0, x, y);
184  return; /* no valid matches? if so, return */
185  }
186 
187  /* Next make a choice, and loop through until we get to it */
188  choice = rndm(0, numat-1);
189  for (at = first_archetype; at != NULL; at = at->next)
190  if ((QUERY_FLAG((&at->clone), FLAG_MONSTER) == QUERY_FLAG(op, FLAG_MONSTER)) && (object_find_free_spot(&at->clone, map, x, y, 0, SIZEOFFREE) != -1)) {
191  if (!choice)
192  break;
193  else
194  choice--;
195  }
196 
197  /* Look through the monster. Unapply anything they have applied,
198  * and remove any spells. Note that if this is extended
199  * to players, that would need to get fixed somehow.
200  */
201  FOR_INV_PREPARE(op, tmp) {
202  if (QUERY_FLAG(tmp, FLAG_APPLIED))
203  apply_manual(op, tmp, 0);
204  if (tmp->type == SPELL) {
205  object_remove(tmp);
206  object_free(tmp, 0);
207  }
208  } FOR_INV_FINISH();
209 
210  /* Preserve some values for the new object */
211  owner = object_get_owner(op);
212  friendly = QUERY_FLAG(op, FLAG_FRIENDLY);
213  if (friendly)
215 
216  object_copy(&(at->clone), op);
217  if (owner != NULL)
218  object_set_owner(op, owner);
219  if (friendly) {
220  SET_FLAG(op, FLAG_FRIENDLY);
221  op->attack_movement = PETMOVE;
223  } else
225 
226  /* Put the new creature on the map */
227  if ((op = object_insert_in_map_at(op, map, owner, 0, x, y)) == NULL)
228  return;
229 
230  if (HAS_RANDOM_ITEMS(op))
232 
233  /* Apply any objects. */
235 }
236 
237 
249 static void polymorph_melt(object *who, object *op) {
250  /* Not unique */
251  char name[MAX_BUF];
252 
253  query_name(op, name, MAX_BUF);
254  if (op->nrof > 1)
256  "The %s glow red, melt and evaporate!",
257  name);
258  else
260  "The %s glows red, melts and evaporates!",
261  name);
262  play_sound_map(SOUND_TYPE_ITEM, op, 0, "evaporate");
263  object_remove(op);
264  object_free(op, 0);
265  return;
266 }
267 
277 static void polymorph_item(object *who, object *op, int level) {
278  archetype *at;
279  int max_value, difficulty, tries = 0, choice, charges = op->stats.food, numat = 0;
280  object *new_ob;
281  mapstruct *m;
282  int16_t x, y;
283 
284  /* We try and limit the maximum value of the changed object. */
285  max_value = op->value*2;
286  if (max_value > 2000*(level/10))
287  max_value = 2000*(level/10)+(max_value-2000*(level/10))/3;
288 
289  /* Look through and try to find matching items. Can't turn into something
290  * invisible. Also, if the value is too high now, it would almost
291  * certainly be too high below.
292  */
293  for (at = first_archetype; at != NULL; at = at->next) {
294  if (at->clone.type == op->type
295  && !at->clone.invisible
296  && at->clone.value > 0
297  && at->clone.value < max_value
298  && !QUERY_FLAG(&at->clone, FLAG_NO_DROP)
299  && !QUERY_FLAG(&at->clone, FLAG_STARTEQUIP))
300  numat++;
301  }
302 
303  if (!numat)
304  return;
305 
306  difficulty = op->magic*5;
307  if (difficulty < 0)
308  difficulty = 0;
309  new_ob = object_new();
310  do {
311  choice = rndm(0, numat-1);
312  for (at = first_archetype; at != NULL; at = at->next) {
313  if (at->clone.type == op->type
314  && !at->clone.invisible
315  && at->clone.value > 0
316  && at->clone.value < max_value
317  && !QUERY_FLAG(&at->clone, FLAG_NO_DROP)
318  && !QUERY_FLAG(&at->clone, FLAG_STARTEQUIP)) {
319  if (!choice)
320  break;
321  else
322  choice--;
323  }
324  }
325  object_copy(&(at->clone), new_ob);
326  fix_generated_item(new_ob, op, difficulty, FABS(op->magic), GT_ENVIRONMENT);
327  ++tries;
328  } while (new_ob->value > max_value && tries < 10);
329  if (new_ob->invisible) {
330  LOG(llevError, "polymorph_item: fix_generated_object made %s invisible?!\n", new_ob->name);
332  return;
333  }
334 
335  /* Unable to generate an acceptable item? Melt it */
336  if (tries == 10) {
337  polymorph_melt(who, op);
339  return;
340  }
341 
342  if (op->nrof && new_ob->nrof) {
343  new_ob->nrof = op->nrof;
344  /* decrease the number of items */
345  if (new_ob->nrof > 2)
346  new_ob->nrof -= rndm(0, op->nrof/2-1);
347  }
348 
349  /* We don't want rings to keep sustenance/hungry status. There are probably
350  * other cases too that should be checked.
351  */
352  if (charges && op->type != RING && op->type != FOOD)
353  op->stats.food = charges;
354 
355  x = op->x;
356  y = op->y;
357  m = op->map;
358  object_remove(op);
360  /*
361  * Don't want objects merged or re-arranged, as it then messes up the
362  * order
363  */
364  object_insert_in_map_at(new_ob, m, new_ob, INS_NO_MERGE|INS_NO_WALK_ON, x, y);
365 }
366 
377 void polymorph(object *op, object *who, int level) {
378  int tmp;
379 
380  /* Can't polymorph players right now */
381  /* polymorphing generators opens up all sorts of abuses */
382  if (op->type == PLAYER || QUERY_FLAG(op, FLAG_GENERATOR))
383  return;
384 
385  if (QUERY_FLAG(op, FLAG_MONSTER)) {
386  polymorph_living(op, level);
387  return;
388  }
389  /* If it is a living object of some other type, don't handle
390  * it now.
391  */
392  if (QUERY_FLAG(op, FLAG_ALIVE))
393  return;
394 
395  /* Don't want to morph flying arrows, etc... */
396  if (FABS(op->speed) > 0.001 && !QUERY_FLAG(op, FLAG_ANIMATE))
397  return;
398 
399  /* Do some sanity checking here. type=0 is unknown, objects
400  * without archetypes are not good. As are a few other
401  * cases.
402  */
403  if (op->type == 0
404  || op->arch == NULL
405  || QUERY_FLAG(op, FLAG_NO_PICK)
406  || op->move_block
407  || op->type == TREASURE)
408  return;
409 
410  tmp = rndm(0, 7);
411  if (tmp)
412  polymorph_item(who, op, level);
413  else
414  polymorph_melt(who, op);
415 }
416 
417 
431 int cast_polymorph(object *op, object *caster, object *spell_ob, int dir) {
432  object *tmp;
433  int range, mflags, maxrange, level;
434  mapstruct *m;
435 
436  if (dir == 0)
437  return 0;
438 
439  maxrange = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
440  level = caster_level(caster, spell_ob);
441  for (range = 1; range < maxrange; range++) {
442  int16_t x = op->x+freearr_x[dir]*range, y = op->y+freearr_y[dir]*range;
443  object *image;
444 
445  m = op->map;
446  mflags = get_map_flags(m, &m, x, y, &x, &y);
447 
448  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
449  break;
450 
451  if (GET_MAP_MOVE_BLOCK(m, x, y)&MOVE_FLY_LOW)
452  break;
453 
454  /* Get the top most object */
455  for (tmp = GET_MAP_OB(m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above)
456  ;
457 
458  /* Now start polymorphing the objects, top down */
460  /* Once we find the floor, no need to go further */
461  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
462  break;
463  polymorph(tmp, op, level);
465  image = arch_to_object(spell_ob->other_arch);
466  image->stats.food = 5;
467  image->speed_left = 0.1;
468  object_insert_in_map_at(image, m, op, 0, x, y);
469  }
470  return 1;
471 }
472 
499 int cast_create_missile(object *op, object *caster, object *spell, int dir, const char *stringarg) {
500  int missile_plus = 0, bonus_plus = 0;
501  const char *missile_name;
502  object *tmp, *missile;
503  tag_t tag;
504 
505  tmp = object_find_by_type_applied(op, BOW);
506  missile_name = tmp != NULL ? tmp->race : "arrow";
507 
508  missile_plus = spell->stats.dam+SP_level_dam_adjust(caster, spell);
509 
510  if (!strcmp(missile_name, "arrows"))
511  missile_name = "arrow";
512  else if (!strcmp(missile_name, "crossbow bolts"))
513  missile_name = "bolt";
514 
515  /* Check if the type (bolt/arrow) was specified with the spell */
516  if ( stringarg && strncmp(stringarg,"of ",3)==0 ) stringarg +=3;
517  if ( stringarg && strncmp(stringarg,"bolt",4)==0 ) {
518  missile_name = "bolt";
519  stringarg += 4;
520  while ( isalpha(*stringarg) ) ++stringarg;
521  while ( *stringarg==' ' ) ++stringarg;
522  }
523  if ( stringarg && strncmp(stringarg,"arrow",5)==0 ) {
524  missile_name = "arrow";
525  stringarg += 5;
526  while ( isalpha(*stringarg) ) ++stringarg;
527  while ( *stringarg==' ' ) ++stringarg;
528  }
529 
530  if (find_archetype(missile_name) == NULL) {
531  LOG(llevDebug, "Cast create_missile: could not find archetype %s\n", missile_name);
532  return 0;
533  }
534  missile = create_archetype(missile_name);
535 
536  if ( stringarg && strncmp(stringarg,"of ",3)==0 ) stringarg +=3;
537  if (stringarg) {
538  /* If it starts with a letter, presume it is a description */
539  if (isalpha(*stringarg)) {
540  artifact *al = find_artifactlist(missile->type)->items;
541 
542  for (; al != NULL; al = al->next)
543  if (!strcasecmp(al->item->name, stringarg))
544  break;
545 
546  if (!al) {
549  "No such object %ss of %s",
550  missile_name, stringarg);
551  return 0;
552  }
553  if (al->item->slaying) {
556  "You are not allowed to create %ss of %s",
557  missile_name, stringarg);
558  return 0;
559  }
560  give_artifact_abilities(missile, al->item);
561  /* These special arrows cost something extra. Don't have them also be
562  * magical - otherwise, in most cases, not enough will be created.
563  * I don't want to get into the parsing both plus and type.
564  */
565  bonus_plus = 1+(al->item->value/5);
566  missile_plus = 0;
567  } else if (atoi(stringarg) < missile_plus)
568  missile_plus = atoi(stringarg);
569  }
570  if (missile_plus > 4)
571  missile_plus = 4;
572  else if (missile_plus < -4)
573  missile_plus = -4;
574 
575  missile->nrof = spell->duration+SP_level_duration_adjust(caster, spell);
576  if (missile->nrof <= (uint32_t)3 * (missile_plus + bonus_plus)) {
579  "This item is too powerful for you to create!");
580  return 0;
581  }
582  missile->nrof -= 3*(missile_plus+bonus_plus);
583  if (missile->nrof < 1)
584  missile->nrof = 1;
585 
586  missile->magic = missile_plus;
587  /* Can't get any money for these objects */
588  missile->value = 0;
589 
590  SET_FLAG(missile, FLAG_IDENTIFIED);
591  tag = missile->count;
592 
593  if (!cast_create_obj(op, missile, dir)
594  && op->type == PLAYER
595  && !object_was_destroyed(missile, tag)) {
596  pick_up(op, missile);
597  }
598  return 1;
599 }
600 
601 
622 int cast_create_food(object *op, object *caster, object *spell_ob, int dir, const char *stringarg) {
623  int food_value;
624  archetype *at = NULL;
625  object *new_op;
626 
627  food_value = spell_ob->stats.food+50*SP_level_duration_adjust(caster, spell_ob);
628 
629  if (stringarg) {
630  at = find_archetype_by_object_type_name(FOOD, stringarg);
631  if (at == NULL)
632  at = find_archetype_by_object_type_name(DRINK, stringarg);
633  if (at == NULL || at->clone.stats.food > food_value)
634  stringarg = NULL;
635  }
636 
637  if (!stringarg) {
638  archetype *at_tmp;
639 
640  /* We try to find the archetype with the maximum food value.
641  * This removes the dependency of hard coded food values in this
642  * function, and addition of new food types is automatically added.
643  * We don't use flesh types because the weight values of those need
644  * to be altered from the donor.
645  */
646 
647  /* We assume the food items don't have multiple parts */
648  for (at_tmp = first_archetype; at_tmp != NULL; at_tmp = at_tmp->next) {
649  if (at_tmp->clone.type == FOOD || at_tmp->clone.type == DRINK) {
650  /* Basically, if the food value is something that is creatable
651  * under the limits of the spell and it is higher than
652  * the item we have now, take it instead.
653  */
654  if (at_tmp->clone.stats.food <= food_value
655  && (!at || at_tmp->clone.stats.food > at->clone.stats.food))
656  at = at_tmp;
657  }
658  }
659  }
660  /* Pretty unlikely (there are some very low food items), but you never
661  * know
662  */
663  if (!at) {
665  "You don't have enough experience to create any food.");
666  return 0;
667  }
668 
669  food_value /= at->clone.stats.food;
670  new_op = object_new();
671  object_copy(&at->clone, new_op);
672  new_op->nrof = food_value;
673 
674  new_op->value = 0;
675  if (new_op->nrof < 1)
676  new_op->nrof = 1;
677 
678  cast_create_obj(op, new_op, dir);
679  return 1;
680 }
681 
700 int probe(object *op, object *caster, object *spell_ob, int dir, int level) {
701  int r, mflags, maxrange;
702  mapstruct *m;
703 
704  if (!dir) {
705  examine_monster(op, op, level);
706  return 1;
707  }
708  maxrange = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
709  for (r = 1; r < maxrange; r++) {
710  int16_t x = op->x+r*freearr_x[dir], y = op->y+r*freearr_y[dir];
711 
712  m = op->map;
713  mflags = get_map_flags(m, &m, x, y, &x, &y);
714 
715  if (mflags&P_OUT_OF_MAP)
716  break;
717 
718  if (!QUERY_FLAG(op, FLAG_WIZCAST) && (mflags&P_NO_MAGIC)) {
720  "Something blocks your magic.");
721  return 0;
722  }
723  if (mflags&P_IS_ALIVE) {
724  FOR_MAP_PREPARE(m, x, y, tmp)
725  if (CAN_PROBE(tmp)) {
727  "You detect something.");
728  examine_monster(op, HEAD(tmp), level);
729  return 1;
730  }
731  FOR_MAP_FINISH();
732  }
733  }
735  "You detect nothing.");
736  return 1;
737 }
738 
739 
757 int makes_invisible_to(object *pl, object *mon) {
758  if (!pl->invisible)
759  return 0;
760  if (pl->type == PLAYER) {
761  /* If race isn't set, then invisible unless it is undead */
762  if (!pl->contr->invis_race) {
763  if (QUERY_FLAG(mon, FLAG_UNDEAD))
764  return 0;
765  return 1;
766  }
767  /* invis_race is set if we get here */
768  if (!strcmp(pl->contr->invis_race, "undead") && is_true_undead(mon))
769  return 1;
770  /* No race, can't be invisible to it */
771  if (!mon->race)
772  return 0;
773  if (strstr(mon->race, pl->contr->invis_race))
774  return 1;
775  /* Nothing matched above, return 0 */
776  return 0;
777  } else {
778  /* monsters are invisible to everything */
779  return 1;
780  }
781 }
782 
804 int cast_invisible(object *op, object *caster, object *spell_ob) {
805  object *tmp;
806 
807  if (op->invisible > 1000) {
809  "You can not extend the duration of your invisibility any further");
810  return 0;
811  }
812 
813  /* Remove the switch with 90% duplicate code - just handle the differences with
814  * and if statement or two.
815  */
816  op->invisible += spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
817  /* max duration */
818  if (op->invisible > 1000)
819  op->invisible = 1000;
820 
821  if (op->type == PLAYER) {
822  if (op->contr->invis_race)
824  if (spell_ob->race)
825  op->contr->invis_race = add_refcount(spell_ob->race);
826  if (QUERY_FLAG(spell_ob, FLAG_MAKE_INVIS))
827  op->contr->tmp_invis = 0;
828  else
829  op->contr->tmp_invis = 1;
830 
831  op->contr->hidden = 0;
832  }
833  if (makes_invisible_to(op, op))
835  "You can't see your hands!");
836  else
838  "You feel more transparent!");
839 
841 
842  /* Only search the active objects - only these should actually do
843  * harm to the player.
844  */
845  for (tmp = active_objects; tmp != NULL; tmp = tmp->active_next)
846  if (tmp->enemy == op)
847  object_set_enemy(tmp, NULL);
848  return 1;
849 }
850 
865 int cast_earth_to_dust(object *op, object *caster, object *spell_ob) {
866  int range, i, j, mflags;
867  int16_t sx, sy;
868  mapstruct *m;
869 
870  if (op->type != PLAYER)
871  return 0;
872 
873  range = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
874 
875  for (i = -range; i < range; i++)
876  for (j = -range; j < range; j++) {
877  sx = op->x+i;
878  sy = op->y+j;
879  m = op->map;
880  mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
881 
882  if (mflags&P_OUT_OF_MAP)
883  continue;
884 
885  /* If the space doesn't block, no wall here to remove
886  * Don't care too much what it blocks - this allows for
887  * any sort of earthwall/airwall/waterwall, etc
888  * type effects.
889  */
890  if (GET_MAP_MOVE_BLOCK(m, sx, sy)) {
891  FOR_MAP_PREPARE(m, sx, sy, tmp)
892  if (tmp && QUERY_FLAG(tmp, FLAG_TEAR_DOWN))
893  hit_player(tmp, 9998, op, AT_PHYSICAL, 0);
894  FOR_MAP_FINISH();
895  }
896  }
897  return 1;
898 }
899 
916 int cast_word_of_recall(object *op, object *caster, object *spell_ob) {
917  object *dummy;
918  int time;
919 
920  if (op->type != PLAYER)
921  return 0;
922 
925  "You feel a force starting to build up inside you.");
926  return 1;
927  }
928 
929  dummy = create_archetype(FORCE_NAME);
930  if (dummy == NULL) {
932  "Oops, program error!");
933  LOG(llevError, "cast_word_of_recall: create_archetype(force) failed!\n");
934  return 0;
935  }
936  time = spell_ob->duration-SP_level_duration_adjust(caster, spell_ob);
937  if (time < 1)
938  time = 1;
939 
940  /* value of speed really doesn't make much difference, as long as it is
941  * positive. Lower value may be useful so that the problem doesn't
942  * do anything really odd if it say a -1000 or something.
943  */
944  dummy->speed = 0.002;
945  object_update_speed(dummy);
946  dummy->speed_left = -dummy->speed*time;
947  dummy->type = SPELL_EFFECT;
948  dummy->subtype = SP_WORD_OF_RECALL;
949 
950  /* If we could take advantage of enter_player_savebed() here, it would be
951  * nice, but until the map load fails, we can't.
952  */
953  EXIT_PATH(dummy) = add_string(op->contr->savebed_map);
954  EXIT_X(dummy) = op->contr->bed_x;
955  EXIT_Y(dummy) = op->contr->bed_y;
956 
957  (void)object_insert_in_ob(dummy, op);
959  "You feel a force starting to build up inside you.");
960  return 1;
961 }
962 
978 int cast_wonder(object *op, object *caster, int dir, object *spell_ob) {
979  object *newspell;
980 
981  if (!rndm(0, 3))
982  return cast_cone(op, caster, dir, spell_ob);
983 
984  if (spell_ob->randomitems) {
985  newspell = generate_treasure(spell_ob->randomitems, caster->level);
986  if (!newspell) {
987  LOG(llevError, "cast_wonder: Unable to get a spell!\n");
988  return 0;
989  }
990  if (newspell->type != SPELL) {
991  LOG(llevError, "cast_wonder: spell returned is not a spell (%d, %s)!\n", newspell->type, newspell->name);
992  return 0;
993  }
994  /* Prevent inifinite recursion */
995  if (newspell->subtype == SP_WONDER) {
996  LOG(llevError, "cast_wonder: spell returned is another wonder spell!\n");
997  return 0;
998  }
999  return cast_spell(op, caster, dir, newspell, NULL);
1000  }
1001  return 1;
1002 }
1003 
1012 int perceive_self(object *op) {
1013  char *cp, buf[MAX_BUF];
1015  if (at == NULL) {
1016  return 1;
1017  }
1018  object *tmp;
1019  const object *god;
1020  int i;
1021  StringBuffer *immunity;
1022 
1023  god = find_god(determine_god(op));
1024  if (god)
1026  "You worship %s",
1027  god->name);
1028  else
1030  "You worship no god");
1031 
1032  tmp = arch_present_in_ob(at, op);
1033 
1034  cp = stringbuffer_finish(describe_item(op, op, 0, NULL));
1035 
1036  if (*cp == '\0' && tmp == NULL)
1038  "You feel very mundane");
1039  else {
1041  "You have:");
1043  cp);
1044  if (tmp != NULL) {
1045  for (i = 0; i < NUM_STATS; i++) {
1046  if (get_attr_value(&tmp->stats, i) < 0) {
1048  "Your %s is depleted by %d",
1049  statname[i], -(get_attr_value(&tmp->stats, i)));
1050  }
1051  }
1052  }
1053  }
1054  free(cp);
1055 
1056  if (op->glow_radius > 0)
1058  "You glow in the dark.");
1059 
1060  immunity = NULL;
1061  for (tmp = op->inv; tmp; tmp = tmp->below) {
1062  if (tmp->type == SIGN) {
1063  if (immunity == NULL) {
1064  immunity = stringbuffer_new();
1065  stringbuffer_append_string(immunity, "You have been exposed to: ");
1066  } else {
1067  stringbuffer_append_string(immunity, ", ");
1068  }
1069  stringbuffer_append_string(immunity, tmp->name);
1070  if (tmp->level > 100)
1071  stringbuffer_append_string(immunity, " (full immunity)");
1072  else if (tmp->level > 70)
1073  stringbuffer_append_string(immunity, " (high immunity)");
1074  else if (tmp->level > 20)
1075  stringbuffer_append_string(immunity, " (partial immunity)");
1076  }
1077  }
1078 
1079  if (immunity != NULL) {
1080  cp = stringbuffer_finish(immunity);
1082  free(cp);
1083  }
1084 
1085  if (is_dragon_pl(op)) {
1086  /* now grab the 'dragon_ability'-force from the player's inventory */
1087  tmp = object_find_by_type_and_arch_name(op, FORCE, "dragon_ability_force");
1088  if (tmp != NULL) {
1089  StringBuffer *levels = NULL;
1090  int i;
1091 
1092  if (tmp->stats.exp == 0) {
1093  snprintf(buf, sizeof(buf), "Your metabolism isn't focused on anything.");
1094  } else {
1095  snprintf(buf, sizeof(buf), "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]);
1096  }
1098  buf);
1099 
1100  for (i = 0; i < NROFATTACKS; i++) {
1101  if (atnr_is_dragon_enabled(i) && tmp->resist[i] > 0) {
1102  if (levels == NULL) {
1103  levels = stringbuffer_new();
1104  stringbuffer_append_string(levels, "Ability levels:\n");
1105  }
1106  stringbuffer_append_printf(levels, "- %s: %d\n", change_resist_msg[i], tmp->resist[i]);
1107  }
1108  }
1109 
1110  if (levels != NULL) {
1111  cp = stringbuffer_finish(levels);
1113  free(cp);
1114  }
1115  }
1116  }
1117  return 1;
1118 }
1119 
1149 int cast_create_town_portal(object *op, object *caster, object *spell, int dir) {
1150  object *dummy, *force, *old_force, *tmp;
1151  archetype *perm_portal;
1152  char portal_name [1024], portal_message [1024];
1153  int16_t exitx, exity;
1154  mapstruct *exitmap;
1155  int op_level, x, y;
1156 
1157  /* Check to see if the map the player is currently on is a per player unique
1158  * map. This can be determined in that per player unique maps have the
1159  * full pathname listed. Ignore if settings.create_home_portals is true.
1160  */
1162  if (!strncmp(op->map->path, settings.localdir, strlen(settings.localdir))) {
1164  "You can't cast that here.");
1165  return 0;
1166  }
1167  }
1168 
1169  /* Check to see if the player is on a transport */
1170  if (op->contr && op->contr->transport) {
1172  "You need to exit the transport to cast that.");
1173  return 0;
1174  }
1175 
1176  /* The first thing to do is to check if we have a marked destination
1177  * dummy is used to make a check inventory for the force
1178  */
1179  dummy = arch_to_object(spell->other_arch);
1180  if (dummy == NULL) {
1182  "Oops, program error!");
1183  LOG(llevError, "object_new failed (force in cast_create_town_portal for %s!\n", op->name);
1184  return 0;
1185  }
1186  force = check_inv_recursive(op, dummy);
1187 
1188  if (force == NULL) {
1189  /* Here we know there is no destination marked up.
1190  * We have 2 things to do:
1191  * 1. Mark the destination in the player inventory.
1192  * 2. Let the player know it worked.
1193  */
1194  free_string(dummy->name);
1195  dummy->name = add_string(op->map->path);
1196  EXIT_X(dummy) = op->x;
1197  EXIT_Y(dummy) = op->y;
1198  dummy->weapontype = op->map->last_reset_time;
1199  object_insert_in_ob(dummy, op);
1201  "You fix this place in your mind and feel that you "
1202  "can come here from anywhere.");
1203  return 1;
1204  }
1206 
1207  /* Here we know where the town portal should go to
1208  * We should kill any existing portal associated with the player.
1209  * Than we should create the 2 portals.
1210  * For each of them, we need:
1211  * - To create the portal with the name of the player+destination map
1212  * - set the owner of the town portal
1213  * - To mark the position of the portal in the player's inventory
1214  * for easier destruction.
1215  *
1216  * The mark works has follow:
1217  * slaying: Existing town portal
1218  * hp, sp : x & y of the associated portal
1219  * name : name of the portal
1220  * race : map the portal is in
1221  */
1222 
1223  /* First step: killing existing town portals */
1224  dummy = create_archetype(spell->race);
1225  if (dummy == NULL) {
1227  "Oops, program error!");
1228  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1229  return 0;
1230  }
1231  perm_portal = find_archetype(spell->slaying);
1232  if (perm_portal == NULL) {
1234  "Oops, program error!");
1235  return 0;
1236  }
1237 
1238  /* To kill a town portal, we go trough the player's inventory,
1239  * for each marked portal in player's inventory,
1240  * -We try load the associated map (if impossible, consider the portal destructed)
1241  * -We find any portal in the specified location.
1242  * If it has the good name, we destruct it.
1243  * -We destruct the force indicating that portal.
1244  */
1245  while ((old_force = check_inv_recursive(op, dummy))) {
1246  exitx = EXIT_X(old_force);
1247  exity = EXIT_Y(old_force);
1248  LOG(llevDebug, "Trying to kill a portal in %s (%d,%d)\n", old_force->race, exitx, exity);
1249 
1250  if (!strncmp(old_force->race, settings.localdir, strlen(settings.localdir)))
1251  exitmap = ready_map_name(old_force->race, MAP_PLAYER_UNIQUE);
1252  else
1253  exitmap = ready_map_name(old_force->race, 0);
1254 
1255  if (exitmap) {
1256  tmp = map_find_by_archetype(exitmap, exitx, exity, perm_portal);
1258  if (tmp->name == old_force->name) {
1259  object_remove(tmp);
1260  object_free(tmp, 0);
1261  break;
1262  }
1264 
1265  /* kill any opening animation there is */
1266  archetype *arch = find_archetype("town_portal_open");
1267  if (arch != NULL) {
1268  tmp = map_find_by_archetype(exitmap, exitx, exity, arch);
1270  if (tmp->name == old_force->name) {
1271  object_remove(tmp);
1273  break;
1274  }
1276  }
1277  }
1278  object_remove(old_force);
1279  object_free(old_force, 0);
1280  LOG(llevDebug, "\n");
1281  }
1283 
1284  /* Creating the portals.
1285  * The very first thing to do is to ensure
1286  * access to the destination map.
1287  * If we can't, don't fizzle. Simply warn player.
1288  * This ensure player pays his mana for the spell
1289  * because HE is responsible for forgetting.
1290  * 'force' is the destination of the town portal, which we got
1291  * from the players inventory above.
1292  */
1293 
1294  /* Ensure exit map is loaded*/
1295  if (!strncmp(force->name, settings.localdir, strlen(settings.localdir)))
1296  exitmap = ready_map_name(force->name, MAP_PLAYER_UNIQUE);
1297  else
1298  exitmap = ready_map_name(force->name, 0);
1299 
1300  /* If we were unable to load (ex. random map deleted), warn player*/
1301  if (exitmap == NULL) {
1303  "Something strange happens. You can't remember where to go!?");
1304  object_remove(force);
1305  object_free(force, 0);
1307  return 1;
1308  } else if (exitmap->last_reset_time != force->weapontype) {
1310  "The spell effect has expired.");
1311  object_remove(force);
1312  object_free(force, 0);
1314  return 1;
1315  }
1316 
1317  op_level = caster_level(caster, spell);
1318  if (op_level < 15)
1319  snprintf(portal_message, 1024, "\nThe air moves around you and\na huge smell of ammonia surrounds you as you pass through %s's tiny portal\nPouah!\n", op->name);
1320  else if (op_level < 30)
1321  snprintf(portal_message, 1024, "\n%s's portal smells of ozone.\nYou do a lot of movements and finally pass through the small hole in the air\n", op->name);
1322  else if (op_level < 60)
1323  snprintf(portal_message, 1024, "\nA shining door opens in the air in front of you, showing you the path to another place.\n");
1324  else
1325  snprintf(portal_message, 1024, "\nAs you walk through %s's portal, flowers come out from the ground around you.\nYou feel awed.\n", op->name);
1326 
1327  /* Create a portal in front of player
1328  * dummy contain the portal and
1329  * force contain the track to kill it later
1330  */
1331 
1332  snprintf(portal_name, 1024, "%s's portal to %s", op->name, force->name);
1333  dummy = create_archetype(spell->slaying); /*The portal*/
1334  if (dummy == NULL) {
1336  "Oops, program error!");
1337  LOG(llevError, "object_new failed (perm_magic_portal) in cast_create_town_portal for %s!\n", op->name);
1338  return 0;
1339  }
1340  EXIT_PATH(dummy) = add_string(force->name);
1341  EXIT_X(dummy) = EXIT_X(force);
1342  EXIT_Y(dummy) = EXIT_Y(force);
1343  FREE_AND_COPY(dummy->name, portal_name);
1344  FREE_AND_COPY(dummy->name_pl, portal_name);
1345  object_set_msg(dummy, portal_message);
1346  dummy->race = add_string(op->name); /*Save the owner of the portal*/
1347 
1348  /* create a nice animation */
1349  tmp = create_archetype("town_portal_open");
1350  FREE_AND_COPY(tmp->name, portal_name);
1351  FREE_AND_COPY(tmp->name_pl, portal_name);
1352  object_insert_in_ob(dummy, tmp);
1353  /* and put it on the floor, when it ends the portal will be on the ground */
1354  cast_create_obj(op, tmp, 0);
1355  x = tmp->x;
1356  y = tmp->y;
1357 
1358  /* Now we need to to create a town portal marker inside the player
1359  * object, so on future castings, we can know that he has an active
1360  * town portal.
1361  */
1362  tmp = create_archetype(spell->race);
1363  if (tmp == NULL) {
1365  "Oops, program error!");
1366  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1367  return 0;
1368  }
1369  tmp->race = add_string(op->map->path);
1370  FREE_AND_COPY(tmp->name, portal_name);
1371  EXIT_X(tmp) = x;
1372  EXIT_Y(tmp) = y;
1373  object_insert_in_ob(tmp, op);
1374 
1375  /* Create a portal in the destination map
1376  * dummy contain the portal and
1377  * force the track to kill it later
1378  * the 'force' variable still contains the 'reminder' of
1379  * where this portal goes to.
1380  */
1381  snprintf(portal_name, 1024, "%s's portal to %s", op->name, op->map->path);
1382  dummy = create_archetype(spell->slaying); /*The portal*/
1383  if (dummy == NULL) {
1385  "Oops, program error!");
1386  LOG(llevError, "object_new failed (perm_magic_portal) in cast_create_town_portal for %s!\n", op->name);
1387  return 0;
1388  }
1389  EXIT_PATH(dummy) = add_string(op->map->path);
1390  EXIT_X(dummy) = op->x;
1391  EXIT_Y(dummy) = op->y;
1392  FREE_AND_COPY(dummy->name, portal_name);
1393  FREE_AND_COPY(dummy->name_pl, portal_name);
1394  object_set_msg(dummy, portal_message);
1395  dummy->race = add_string(op->name); /*Save the owner of the portal*/
1396 
1397  /* animation here too */
1398  tmp = create_archetype("town_portal_open");
1399  FREE_AND_COPY(tmp->name, portal_name);
1400  FREE_AND_COPY(tmp->name_pl, portal_name);
1401  object_insert_in_ob(dummy, tmp);
1402  /* and put it on the floor, when it ends the portal will be on the ground */
1403  object_insert_in_map_at(tmp, exitmap, op, 0, EXIT_X(force), EXIT_Y(force));
1404  x = tmp->x;
1405  y = tmp->y;
1406 
1407  /* Now we create another town portal marker that
1408  * points back to the one we just made
1409  */
1410  tmp = create_archetype(spell->race);
1411  if (tmp == NULL) {
1413  "Oops, program error!");
1414  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1415  return 0;
1416  }
1417  tmp->race = add_string(force->name);
1418  FREE_AND_COPY(tmp->name, portal_name);
1419  EXIT_X(tmp) = x;
1420  EXIT_Y(tmp) = y;
1421  object_insert_in_ob(tmp, op);
1422 
1423  /* Describe the player what happened
1424  */
1426  "You see air moving and showing you the way home.");
1427  object_remove(force); /* Delete the force inside the player*/
1428  object_free(force, 0);
1429  return 1;
1430 }
1431 
1432 
1450 int magic_wall(object *op, object *caster, int dir, object *spell_ob) {
1451  object *tmp, *tmp2;
1452  int i, posblocked, negblocked, maxrange;
1453  int16_t x, y;
1454  mapstruct *m;
1455  const char *name;
1456  archetype *at;
1457 
1458  if (!dir) {
1459  dir = op->facing;
1460  x = op->x;
1461  y = op->y;
1462  } else {
1463  x = op->x+freearr_x[dir];
1464  y = op->y+freearr_y[dir];
1465  }
1466  m = op->map;
1467 
1468  if ((spell_ob->move_block || x != op->x || y != op->y)
1469  && (get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE)
1470  || ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) == spell_ob->move_block))) {
1472  "Something is in the way.");
1473  return 0;
1474  }
1475  if (spell_ob->other_arch) {
1476  tmp = arch_to_object(spell_ob->other_arch);
1477  } else if (spell_ob->race) {
1478  char buf1[MAX_BUF];
1479 
1480  snprintf(buf1, sizeof(buf1), spell_ob->race, dir);
1481  at = find_archetype(buf1);
1482  if (!at) {
1483  LOG(llevError, "summon_wall: Unable to find archetype %s\n", buf1);
1485  "This spell is broken.");
1486  return 0;
1487  }
1488  tmp = arch_to_object(at);
1489  } else {
1490  LOG(llevError, "magic_wall: spell %s lacks other_arch\n", spell_ob->name);
1491  return 0;
1492  }
1493 
1494  if (tmp->type == SPELL_EFFECT) {
1495  tmp->attacktype = spell_ob->attacktype;
1496  tmp->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1497  tmp->stats.dam = spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob);
1498  tmp->range = 0;
1499  } else if (QUERY_FLAG(tmp, FLAG_ALIVE)) {
1500  tmp->stats.hp = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1501  tmp->stats.maxhp = tmp->stats.hp;
1502  object_set_owner(tmp, op);
1503  set_spell_skill(op, caster, spell_ob, tmp);
1504  }
1505  if (QUERY_FLAG(spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG(tmp, FLAG_IS_USED_UP)) {
1506  tmp->stats.food = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1507  SET_FLAG(tmp, FLAG_IS_USED_UP);
1508  }
1509  if (QUERY_FLAG(spell_ob, FLAG_TEAR_DOWN)) {
1510  tmp->stats.hp = spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob);
1511  tmp->stats.maxhp = tmp->stats.hp;
1512  SET_FLAG(tmp, FLAG_TEAR_DOWN);
1513  SET_FLAG(tmp, FLAG_ALIVE);
1514  }
1515 
1516  /* This can't really hurt - if the object doesn't kill anything,
1517  * these fields just won't be used.
1518  */
1519  object_set_owner(tmp, op);
1520  set_spell_skill(op, caster, spell_ob, tmp);
1521  tmp->level = caster_level(caster, spell_ob)/2;
1522 
1523  name = tmp->name;
1524  if ((tmp = object_insert_in_map_at(tmp, m, op, 0, x, y)) == NULL) {
1526  "Something destroys your %s",
1527  name);
1528  return 0;
1529  }
1530  /* If this is a spellcasting wall, need to insert the spell object */
1531  if (tmp->other_arch && tmp->other_arch->clone.type == SPELL)
1533 
1534  /* This code causes the wall to extend some distance in
1535  * each direction, or until an obstruction is encountered.
1536  * posblocked and negblocked help determine how far the
1537  * created wall can extend, it won't go extend through
1538  * blocked spaces.
1539  */
1540  maxrange = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
1541  posblocked = 0;
1542  negblocked = 0;
1543 
1544  for (i = 1; i <= maxrange; i++) {
1545  int dir2;
1546 
1547  dir2 = (dir < 4) ? (dir+2) : dir-2;
1548 
1549  x = tmp->x+i*freearr_x[dir2];
1550  y = tmp->y+i*freearr_y[dir2];
1551  m = tmp->map;
1552 
1553  if (!(get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE))
1554  && ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block)
1555  && !posblocked) {
1556  tmp2 = object_new();
1557  object_copy(tmp, tmp2);
1558  object_insert_in_map_at(tmp2, m, op, 0, x, y);
1559  /* If this is a spellcasting wall, need to insert the spell object */
1560  if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
1562  } else
1563  posblocked = 1;
1564 
1565  x = tmp->x-i*freearr_x[dir2];
1566  y = tmp->y-i*freearr_y[dir2];
1567  m = tmp->map;
1568 
1569  if (!(get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE))
1570  && ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block)
1571  && !negblocked) {
1572  tmp2 = object_new();
1573  object_copy(tmp, tmp2);
1574  object_insert_in_map_at(tmp2, m, op, 0, x, y);
1575  if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
1577  } else
1578  negblocked = 1;
1579  }
1580 
1581  if (QUERY_FLAG(tmp, FLAG_BLOCKSVIEW))
1582  update_all_los(op->map, op->x, op->y);
1583 
1584  return 1;
1585 }
1586 
1603 int dimension_door(object *op, object *caster, object *spob, int dir) {
1604  uint32_t dist, maxdist;
1605  int mflags;
1606  mapstruct *m;
1607  int16_t sx, sy;
1608 
1609  if (op->type != PLAYER)
1610  return 0;
1611 
1612  if (!dir) {
1614  "In what direction?");
1615  return 0;
1616  }
1617 
1618  /* Given the new outdoor maps, can't let players dimension door for
1619  * ever, so put limits in.
1620  */
1621  maxdist = spob->range+SP_level_range_adjust(caster, spob);
1622 
1623  if (op->contr->count) {
1624  if (op->contr->count > maxdist) {
1626  "You can't dimension door that far!");
1627  return 0;
1628  }
1629 
1630  for (dist = 0; dist < op->contr->count; dist++) {
1631  mflags = get_map_flags(op->map, &m,
1632  op->x+freearr_x[dir]*(dist+1),
1633  op->y+freearr_y[dir]*(dist+1),
1634  &sx, &sy);
1635 
1636  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
1637  break;
1638 
1639  if ((mflags&P_BLOCKSVIEW)
1640  && OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1641  break;
1642  }
1643 
1644  if (dist < op->contr->count) {
1646  "Something blocks the magic of the spell.");
1647  op->contr->count = 0;
1648  return 0;
1649  }
1650  op->contr->count = 0;
1651 
1652  /* Remove code that puts player on random space on maps. IMO,
1653  * a lot of maps probably have areas the player should not get to,
1654  * but may not be marked as NO_MAGIC (as they may be bounded
1655  * by such squares). Also, there are probably treasure rooms and
1656  * lots of other maps that protect areas with no magic, but the
1657  * areas themselves don't contain no magic spaces.
1658  */
1659  /* This call here is really just to normalize the coordinates */
1660  mflags = get_map_flags(op->map, &m, op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist,
1661  &sx, &sy);
1662  if (mflags&P_IS_ALIVE || OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) {
1664  "You cast your spell, but nothing happens.");
1665  return 1; /* Maybe the penalty should be more severe... */
1666  }
1667  } else {
1668  /* Player didn't specify a distance, so lets see how far
1669  * we can move the player. Don't know why this stopped on
1670  * spaces that blocked the players view.
1671  */
1672 
1673  for (dist = 0; dist < maxdist; dist++) {
1674  mflags = get_map_flags(op->map, &m,
1675  op->x+freearr_x[dir]*(dist+1),
1676  op->y+freearr_y[dir]*(dist+1),
1677  &sx, &sy);
1678 
1679  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
1680  break;
1681 
1682  if ((mflags&P_BLOCKSVIEW)
1683  && OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1684  break;
1685  }
1686 
1687  /* If the destination is blocked, keep backing up until we
1688  * find a place for the player.
1689  */
1690  for (; dist > 0; dist--) {
1691  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))
1692  continue;
1693 
1694  if (!OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1695  break;
1696  }
1697  if (!dist) {
1699  "Your spell failed!");
1700  return 0;
1701  }
1702  }
1703 
1704  if (op->contr->transport && op->contr->transport->type == TRANSPORT) {
1705  ob_apply(op->contr->transport, op, 0);
1706  if (op->contr->transport) {
1708  "Your spell failed!");
1709  return 0;
1710  }
1711  }
1712 
1713  /* Actually move the player now */
1714  object_remove(op);
1715  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)
1716  return 1;
1717 
1718  if (op->type == PLAYER) {
1719  map_newmap_cmd(&op->contr->socket);
1721  }
1722  op->speed_left = -FABS(op->speed)*5; /* Freeze them for a short while */
1723  return 1;
1724 }
1725 
1726 
1739 int cast_heal(object *op, object *caster, object *spell, int dir) {
1740  object *target;
1741  archetype *at;
1742  object *poison;
1743  int heal = 0, success = 0;
1744 
1745  target = find_target_for_friendly_spell(op, dir);
1746 
1747  if (target == NULL)
1748  return 0;
1749 
1750  /* Figure out how many hp this spell might cure.
1751  * could be zero if this spell heals effects, not damage.
1752  */
1753  heal = spell->stats.dam;
1754  if (spell->stats.hp)
1755  heal += random_roll(spell->stats.hp, 6, op, PREFER_HIGH)+spell->stats.hp;
1756 
1757  if (heal) {
1758  if (target->stats.hp >= target->stats.maxhp) {
1760  "You are already fully healed.");
1761  } else {
1762  /* See how many points we actually heal. Instead of messages
1763  * based on type of spell, we instead do messages based
1764  * on amount of damage healed.
1765  */
1766  if (heal > (target->stats.maxhp-target->stats.hp))
1767  heal = target->stats.maxhp-target->stats.hp;
1768  target->stats.hp += heal;
1769 
1770  if (target->stats.hp >= target->stats.maxhp) {
1772  "You feel just fine!");
1773  } else if (heal > 50) {
1775  "Your wounds close!");
1776  } else if (heal > 25) {
1778  "Your wounds mostly close.");
1779  } else if (heal > 10) {
1781  "Your wounds start to fade.");
1782  } else {
1784  "Your wounds start to close.");
1785  }
1786  success = 1;
1787  }
1788  }
1789  if (spell->attacktype&AT_DISEASE)
1790  if (cure_disease(target, op, caster && caster->type != PLAYER ? caster->skill : spell->skill))
1791  success = 1;
1792 
1793  if (spell->attacktype&AT_POISON) {
1794  at = find_archetype("poisoning");
1795  if (at != NULL) {
1796  poison = arch_present_in_ob(at, target);
1797  if (poison) {
1798  success = 1;
1800  "Your body feels cleansed");
1801  poison->stats.food = 1;
1802  }
1803  }
1804  }
1805  if (spell->attacktype&AT_CONFUSION) {
1806  poison = object_present_in_ob_by_name(FORCE, "confusion", target);
1807  if (poison) {
1808  success = 1;
1810  "Your mind feels clearer");
1811  poison->duration = 1;
1812  }
1813  }
1814  if (spell->attacktype&AT_BLIND) {
1815  at = find_archetype("blindness");
1816  if (at != NULL) {
1817  poison = arch_present_in_ob(at, target);
1818  if (poison) {
1819  success = 1;
1821  "Your vision begins to return.");
1822  poison->stats.food = 1;
1823  }
1824  }
1825  }
1826  if (spell->last_sp && target->stats.sp < target->stats.maxsp) {
1827  target->stats.sp += spell->last_sp;
1828  if (target->stats.sp > target->stats.maxsp)
1829  target->stats.sp = target->stats.maxsp;
1830  success = 1;
1832  "Magical energies surge through your body!");
1833  }
1834  if (spell->last_grace && target->stats.grace < target->stats.maxgrace) {
1835  target->stats.grace += spell->last_grace;
1836  if (target->stats.grace > target->stats.maxgrace)
1837  target->stats.grace = target->stats.maxgrace;
1838  success = 1;
1840  "You feel redeemed with you god!");
1841  }
1842  if (spell->stats.food && target->stats.food < MAX_FOOD) {
1843  target->stats.food += spell->stats.food;
1844  if (target->stats.food > MAX_FOOD)
1845  target->stats.food = MAX_FOOD;
1846  success = 1;
1847  /* We could do something a bit better like the messages for healing above */
1849  "You feel your belly fill with food");
1850  }
1851 
1852  if (spell->other_arch != NULL && target->map != NULL) {
1853  object_insert_in_map_at(arch_to_object(spell->other_arch), target->map, NULL, INS_ON_TOP, target->x, target->y);
1854  }
1855 
1856  return success;
1857 }
1858 
1859 
1865 static const char *const no_gain_msgs[NUM_STATS] = {
1866  "You grow no stronger.",
1867  "You grow no more agile.",
1868  "You don't feel any healthier.",
1869  "no wis",
1870  "You are no easier to look at.",
1871  "no int",
1872  "no pow"
1873 };
1874 
1894 int cast_change_ability(object *op, object *caster, object *spell_ob, int dir, int silent) {
1895  object *tmp;
1896  object *force = NULL;
1897  int i;
1898 
1899  /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
1900  if (dir != 0) {
1901  tmp = find_target_for_friendly_spell(op, dir);
1902  } else {
1903  tmp = op;
1904  }
1905 
1906  if (tmp == NULL)
1907  return 0;
1908 
1909  /* If we've already got a force of this type, don't add a new one. */
1910  FOR_INV_PREPARE(tmp, tmp2)
1911  if (tmp2->type == FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
1912  if (tmp2->name == spell_ob->name) {
1913  force = tmp2; /* the old effect will be "refreshed" */
1914  break;
1915  } else if (spell_ob->race && spell_ob->race == tmp2->name) {
1916  if (!silent)
1918  "You can not cast %s while %s is in effect",
1919  spell_ob->name, tmp2->name_pl);
1920  return 0;
1921  }
1922  }
1923  FOR_INV_FINISH();
1924  if (force == NULL) {
1925  force = create_archetype(FORCE_NAME);
1926  force->subtype = FORCE_CHANGE_ABILITY;
1927  free_string(force->name);
1928  if (spell_ob->race)
1929  force->name = add_refcount(spell_ob->race);
1930  else
1931  force->name = add_refcount(spell_ob->name);
1932  free_string(force->name_pl);
1933  force->name_pl = add_refcount(spell_ob->name);
1934  } else {
1935  int duration;
1936 
1937  duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
1938  if (duration > force->duration) {
1939  force->duration = duration;
1941  "You recast the spell while in effect.");
1942 
1943  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
1944  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
1945  }
1946 
1947  } else {
1949  "Recasting the spell had no effect.");
1950  }
1951  return 1;
1952  }
1953  force->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
1954  if (op->type == PLAYER)
1955  store_spell_expiry(force);
1956  force->speed = 1.0;
1957  force->speed_left = -1.0;
1958  SET_FLAG(force, FLAG_APPLIED);
1959 
1960  /* Now start processing the effects. First, protections */
1961  for (i = 0; i < NROFATTACKS; i++) {
1962  if (spell_ob->resist[i]) {
1963  force->resist[i] = spell_ob->resist[i]+SP_level_dam_adjust(caster, spell_ob);
1964  if (force->resist[i] > 100)
1965  force->resist[i] = 100;
1966  }
1967  }
1968  if (spell_ob->stats.hp)
1969  force->stats.hp = spell_ob->stats.hp+SP_level_dam_adjust(caster, spell_ob);
1970 
1971  if (tmp->type == PLAYER) {
1972  /* Stat adjustment spells */
1973  for (i = 0; i < NUM_STATS; i++) {
1974  int8_t stat = get_attr_value(&spell_ob->stats, i), k, sm;
1975 
1976  if (stat) {
1977  sm = 0;
1978  for (k = 0; k < stat; k++)
1979  sm += rndm(1, 3);
1980 
1981  if ((get_attr_value(&tmp->stats, i)+sm) > (15+5*stat)) {
1982  sm = (15+5*stat)-get_attr_value(&tmp->stats, i);
1983  if (sm < 0)
1984  sm = 0;
1985  }
1986  set_attr_value(&force->stats, i, sm);
1987  if (!sm)
1989  no_gain_msgs[i]);
1990  }
1991  }
1992  }
1993 
1994  force->move_type = spell_ob->move_type;
1995 
1996  if (QUERY_FLAG(spell_ob, FLAG_SEE_IN_DARK))
1997  SET_FLAG(force, FLAG_SEE_IN_DARK);
1998 
1999  if (QUERY_FLAG(spell_ob, FLAG_XRAYS))
2000  SET_FLAG(force, FLAG_XRAYS);
2001 
2002  /* Haste/bonus speed */
2003  if (spell_ob->stats.exp) {
2004  if (op->speed > 0.5)
2005  force->stats.exp = (float)spell_ob->stats.exp/(op->speed+0.5);
2006  else
2007  force->stats.exp = spell_ob->stats.exp;
2008  }
2009 
2010  force->stats.wc = spell_ob->stats.wc;
2011  force->stats.ac = spell_ob->stats.ac;
2012  force->attacktype = spell_ob->attacktype;
2013 
2014  SET_FLAG(tmp, FLAG_NO_FIX_PLAYER); /* we don't want object_insert_in_ob() to call fix_object. */
2015  object_insert_in_ob(force, tmp);
2017  change_abil(tmp, force); /* Display any relevant messages, and call fix_object to update the player */
2018 
2019  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
2020  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
2021  }
2022 
2023  return 1;
2024 }
2025 
2042 int cast_bless(object *op, object *caster, object *spell_ob, int dir) {
2043  int i;
2044  const object *god = find_god(determine_god(op));
2045  object *force = NULL, *tmp;
2046 
2047  /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
2048  if (dir != 0) {
2049  tmp = find_target_for_friendly_spell(op, dir);
2050  } else {
2051  tmp = op;
2052  }
2053 
2054  /* If we've already got a force of this type, don't add a new one. */
2055  FOR_INV_PREPARE(tmp, tmp2)
2056  if (tmp2->type == FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
2057  if (tmp2->name == spell_ob->name) {
2058  force = tmp2; /* the old effect will be "refreshed" */
2059  break;
2060  } else if (spell_ob->race && spell_ob->race == tmp2->name) {
2062  "You can not cast %s while %s is in effect",
2063  spell_ob->name, tmp2->name_pl);
2064  return 0;
2065  }
2066  }
2067  FOR_INV_FINISH();
2068  if (force == NULL) {
2069  force = create_archetype(FORCE_NAME);
2070  force->subtype = FORCE_CHANGE_ABILITY;
2071  free_string(force->name);
2072  if (spell_ob->race)
2073  force->name = add_refcount(spell_ob->race);
2074  else
2075  force->name = add_refcount(spell_ob->name);
2076  free_string(force->name_pl);
2077  force->name_pl = add_refcount(spell_ob->name);
2078  } else {
2079  int duration;
2080 
2081  duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
2082  if (duration > force->duration) {
2083  force->duration = duration;
2085  "You recast the spell while in effect.");
2086  } else {
2088  "Recasting the spell had no effect.");
2089  }
2090  return 0;
2091  }
2092  force->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
2093  force->speed = 1.0;
2094  force->speed_left = -1.0;
2095 
2096  if (!god) {
2098  "Your blessing seems empty.");
2099  } else {
2100  /* Only give out good benefits, and put a max on it */
2101  const int16_t resist_max = spell_ob->resist[ATNR_GODPOWER];
2102  for (i = 0; i < NROFATTACKS; i++) {
2103  if (god->resist[i] > 0) {
2104  force->resist[i] = MIN(god->resist[i], resist_max);
2105  }
2106  }
2107  // Also grant appropriate amount of godpower resistance.
2108  force->resist[ATNR_GODPOWER] = spell_ob->resist[ATNR_GODPOWER];
2109 
2110  force->path_attuned |= god->path_attuned;
2111  if (spell_ob->attacktype) {
2112  force->attacktype |= god->attacktype|AT_PHYSICAL;
2113  if (god->slaying)
2114  force->slaying = add_string(god->slaying);
2115  }
2116  if (tmp != op) {
2118  "You bless %s.",
2119  tmp->name);
2121  "%s blessed you.",
2122  op->name);
2123  } else {
2125  "You are blessed by %s!",
2126  god->name);
2127  }
2128  }
2129  force->stats.wc = spell_ob->stats.wc;
2130  force->stats.ac = spell_ob->stats.ac;
2131 
2132  store_spell_expiry(force);
2133  object_insert_in_ob(force, tmp);
2134  SET_FLAG(force, FLAG_APPLIED);
2135  change_abil(tmp, force); /* To display any messages, will call fix_object() */
2136 
2137  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
2138  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
2139  }
2140  return 1;
2141 }
2142 
2143 
2144 
2145 /*
2146  * Alchemy code by Mark Wedel
2147  *
2148  * This code adds a new spell, called alchemy. Alchemy will turn
2149  * objects to gold nuggets, the value of the gold nuggets being
2150  * from 5% to 40% of that of the item itself depending on casting level.
2151  * It uses the value of the object before charisma adjustments, because
2152  * the nuggets themselves will be will be adjusted by charisma when sold.
2153  *
2154  * Large nuggets are worth 25 gp each (base). You will always get
2155  * the maximum number of large nuggets you could get.
2156  * Small nuggets are worth 1 gp each (base). You will get from 0
2157  * to the max amount of small nuggets as you could get.
2158  *
2159  * For example, if an item is worth 110 gold, you will get
2160  * 4 large nuggets, and from 0-10 small nuggets.
2161  *
2162  * There is also a chance (1:30) that you will get nothing at all
2163  * for the object. There is also a maximum weight that will be
2164  * alchemied.
2165  */
2166 
2167 #define SMALL_NUGGET "smallnugget"
2168 #define LARGE_NUGGET "largenugget"
2169 
2184 static void alchemy_object(float value_adj, object *obj, int *small_nuggets, int *large_nuggets, int *weight) {
2185  uint64_t value = price_base(obj);
2186  uint64_t small_value, large_value;
2188  /* Multiply the value of the object by value_adj, which should range
2189  * from 0.05 to 0.40. Set value to 0 instead if unpaid.
2190  */
2191  if (QUERY_FLAG(obj, FLAG_UNPAID))
2192  value = 0;
2193  else
2194  value *= value_adj;
2195 
2196  archetype *small_nugget_arch = find_archetype(SMALL_NUGGET);
2197  if (small_nugget_arch == NULL) {
2198  return;
2199  }
2200  small_value = price_base(&small_nugget_arch->clone);
2201  archetype *large_nugget_arch = find_archetype(LARGE_NUGGET);
2202  if (large_nugget_arch == NULL) {
2203  return;
2204  }
2205  large_value = price_base(&large_nugget_arch->clone);
2206 
2207  /* Give half of what value_adj says when we alchemy money (This should
2208  * hopefully make it so that it isn't worth it to alchemy money, sell
2209  * the nuggets, alchemy the gold from that, etc.
2210  */
2211  if (value && (obj->type == MONEY || obj->type == GEM))
2212  value /= 2;
2213 
2214  if ((obj->value > 0) && rndm(0, 29)) {
2215  int count;
2216 
2217  assert(large_value != 0 && small_value != 0);
2218  count = value/large_value;
2219  *large_nuggets += count;
2220  value -= (uint64_t)count*large_value;
2221  count = value/small_value;
2222  *small_nuggets += count;
2223  }
2224 
2225  /* Turn 25 small nuggets into 1 large nugget. If the value
2226  * of large nuggets is not evenly divisable by the small nugget
2227  * value, take off an extra small_nugget (Assuming small_nuggets!=0)
2228  */
2229  if (*small_nuggets*small_value >= large_value) {
2230  assert(small_value != 0);
2231  (*large_nuggets)++;
2232  *small_nuggets -= large_value/small_value;
2233  if (*small_nuggets && large_value%small_value)
2234  (*small_nuggets)--;
2235  }
2236 
2237  if (weight != NULL) {
2238  *weight += obj->weight;
2239  }
2240 
2241  object_remove(obj);
2243 }
2244 
2258 static void place_alchemy_objects(object *op, mapstruct *m, int small_nuggets, int large_nuggets, int x, int y) {
2259  object *tmp;
2260  int flag = 0;
2261 
2262  /* Put any nuggets below the player, but we can only pass this
2263  * flag if we are on the same space as the player
2264  */
2265  if (x == op->x && y == op->y && op->map == m)
2266  flag = INS_BELOW_ORIGINATOR;
2267 
2268  if (small_nuggets) {
2270  tmp-> nrof = small_nuggets;
2271  object_insert_in_map_at(tmp, m, op, flag, x, y);
2272  }
2273  if (large_nuggets) {
2275  tmp-> nrof = large_nuggets;
2276  object_insert_in_map_at(tmp, m, op, flag, x, y);
2277  }
2278 }
2279 
2294 int alchemy(object *op, object *caster, object *spell_ob) {
2295  int x, y, weight = 0, weight_max, large_nuggets, small_nuggets, mflags;
2296  int16_t nx, ny;
2297  float value_adj;
2298  mapstruct *mp;
2299 
2300  if (op->type != PLAYER)
2301  return 0;
2302 
2303  /* Put a maximum weight of items that can be alchemied. Limits the power
2304  * some, and also prevents people from alcheming every table/chair/clock
2305  * in sight
2306  */
2307  weight_max = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
2308  weight_max *= 1000;
2309 
2310  /* Set value_adj to be a multiplier for how much of the original value
2311  * will be in the nuggets. Starts at 0.05, increasing by 0.01 per casting
2312  * level, maxing out at 0.40.
2313  */
2314  value_adj = (SP_level_dam_adjust(caster, spell_ob)/100.00)+0.05;
2315 
2316  if (value_adj > 0.40)
2317  value_adj = 0.40;
2318 
2319  for (y = op->y-1; y <= op->y+1; y++) {
2320  for (x = op->x-1; x <= op->x+1; x++) {
2321  nx = x;
2322  ny = y;
2323 
2324  mp = op->map;
2325 
2326  mflags = get_map_flags(mp, &mp, nx, ny, &nx, &ny);
2327 
2328  if (mflags&(P_OUT_OF_MAP|P_NO_MAGIC))
2329  continue;
2330 
2331  /* Treat alchemy a little differently - most spell effects
2332  * use fly as the movement type - for alchemy, consider it
2333  * ground level effect.
2334  */
2335  if (GET_MAP_MOVE_BLOCK(mp, nx, ny)&MOVE_WALK)
2336  continue;
2337 
2338  small_nuggets = 0;
2339  large_nuggets = 0;
2340 
2341  FOR_MAP_PREPARE(mp, nx, ny, tmp) {
2342  if (tmp->weight > 0 && !QUERY_FLAG(tmp, FLAG_NO_PICK)
2343  && !QUERY_FLAG(tmp, FLAG_ALIVE)
2344  && !QUERY_FLAG(tmp, FLAG_IS_CAULDRON)) {
2345  if (tmp->inv) {
2346  FOR_INV_PREPARE(tmp, tmp1)
2347  if (tmp1->weight > 0 && !QUERY_FLAG(tmp1, FLAG_NO_PICK)
2348  && !QUERY_FLAG(tmp1, FLAG_ALIVE)
2349  && !QUERY_FLAG(tmp1, FLAG_IS_CAULDRON))
2350  alchemy_object(value_adj, tmp1, &small_nuggets, &large_nuggets, &weight);
2351  FOR_INV_FINISH();
2352  }
2353  alchemy_object(value_adj, tmp, &small_nuggets, &large_nuggets, &weight);
2354 
2355  if (weight > weight_max) {
2356  place_alchemy_objects(op, mp, small_nuggets, large_nuggets, nx, ny);
2357  return 1;
2358  }
2359  } /* is alchemable object */
2360  } FOR_MAP_FINISH(); /* process all objects on this space */
2361 
2362  /* Insert all the nuggets at one time. This probably saves time, but
2363  * it also prevents us from alcheming nuggets that were just created
2364  * with this spell.
2365  */
2366  place_alchemy_objects(op, mp, small_nuggets, large_nuggets, nx, ny);
2367  }
2368  }
2369 
2370  /* reset this so that if player standing on a big pile of stuff,
2371  * it is redrawn properly.
2372  */
2373  op->contr->socket.look_position = 0;
2374  return 1;
2375 }
2376 
2377 
2392 int remove_curse(object *op, object *caster, object *spell) {
2393  int success = 0, was_one = 0;
2394 
2395  FOR_INV_PREPARE(op, tmp)
2396  if (QUERY_FLAG(tmp, FLAG_APPLIED)
2397  && ((QUERY_FLAG(tmp, FLAG_CURSED) && QUERY_FLAG(spell, FLAG_CURSED))
2398  || (QUERY_FLAG(tmp, FLAG_DAMNED) && QUERY_FLAG(spell, FLAG_DAMNED)))) {
2399  was_one++;
2400  if (tmp->level <= caster_level(caster, spell)) {
2401  success++;
2402  if (QUERY_FLAG(spell, FLAG_DAMNED))
2403  CLEAR_FLAG(tmp, FLAG_DAMNED);
2404 
2405  CLEAR_FLAG(tmp, FLAG_CURSED);
2407  tmp->value = 0; /* Still can't sell it */
2408  if (op->type == PLAYER)
2409  esrv_update_item(UPD_FLAGS, op, tmp);
2410  }
2411  }
2412  FOR_INV_FINISH();
2413 
2414  if (op->type == PLAYER) {
2415  if (success) {
2417  "You feel like some of your items are looser now.");
2418  } else {
2419  if (was_one)
2421  "You failed to remove the curse.");
2422  else
2424  "You are not using any cursed items.");
2425  }
2426  }
2427  return success;
2428 }
2429 
2442 int cast_item_curse_or_curse(object *op, object *caster, object *spell_ob) {
2443  object *marked = find_marked_object(op);
2444  char name[HUGE_BUF];
2445 
2446  if (!marked) {
2448  "You need to mark an item first!");
2449  return 0;
2450  }
2451 
2452  if ((QUERY_FLAG(marked, FLAG_CURSED) && QUERY_FLAG(spell_ob, FLAG_CURSED))
2453  || (QUERY_FLAG(marked, FLAG_BLESSED) && QUERY_FLAG(spell_ob, FLAG_BLESSED))) {
2455  "The spell has no effect");
2456  return 0;
2457  }
2458 
2459  query_short_name(marked, name, HUGE_BUF);
2460  if (QUERY_FLAG(spell_ob, FLAG_CURSED)) {
2462  "Your %s emits a dark light for a few seconds.", name);
2463  SET_FLAG(marked, FLAG_CURSED);
2464  CLEAR_FLAG(marked, FLAG_KNOWN_CURSED);
2465  CLEAR_FLAG(marked, FLAG_IDENTIFIED);
2466  esrv_update_item(UPD_FLAGS, op, marked);
2467  return 1;
2468  }
2469 
2471  "Your %s glows blue for a few seconds.", name);
2472  SET_FLAG(marked, FLAG_BLESSED);
2473  SET_FLAG(marked, FLAG_KNOWN_BLESSED);
2474  SET_FLAG(marked, FLAG_STARTEQUIP);
2475  esrv_update_item(UPD_FLAGS, op, marked);
2476  return 1;
2477 }
2478 
2493 int cast_identify(object *op, object *caster, object *spell) {
2494  int success = 0, num_ident;
2495  char desc[MAX_BUF];
2496 
2497  num_ident = spell->stats.dam+SP_level_dam_adjust(caster, spell);
2498 
2499  if (num_ident < 1)
2500  num_ident = 1;
2501 
2502  FOR_INV_PREPARE(op, tmp)
2503  if (!tmp->invisible && !is_identified(tmp)) {
2504  tmp = identify(tmp);
2505  if (op->type == PLAYER) {
2507  "You have %s.",
2508  ob_describe(tmp, op, 1, desc, sizeof(desc)));
2509  if (tmp->msg) {
2511  "The item has a story:\n%s",
2512  tmp->msg);
2513  }
2514  }
2515  num_ident--;
2516  success = 1;
2517  if (!num_ident)
2518  break;
2519  }
2520  FOR_INV_FINISH();
2521  /* If all the power of the spell has been used up, don't go and identify
2522  * stuff on the floor. Only identify stuff on the floor if the spell
2523  * was not fully used.
2524  */
2525  if (num_ident) {
2526  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp)
2527  if (!tmp->invisible && !is_identified(tmp)) {
2528  tmp = identify(tmp);
2529  if (op->type == PLAYER) {
2531  "On the ground is %s.",
2532  ob_describe(tmp, op, 1, desc, sizeof(desc)));
2533  if (tmp->msg) {
2535  "The item has a story:\n%s",
2536  tmp->msg);
2537  }
2539  }
2540  num_ident--;
2541  success = 1;
2542  if (!num_ident)
2543  break;
2544  }
2545  FOR_MAP_FINISH();
2546  }
2547  if (!success)
2549  "You can't reach anything unidentified.");
2550  else {
2551  spell_effect(spell, op->x, op->y, op->map, op);
2552  }
2553  return success;
2554 }
2555 
2568 int cast_detection(object *op, object *caster, object *spell) {
2569  object *tmp, *last, *detect;
2570  const object *god;
2571  int done_one, range, mflags, floor, level;
2572  int16_t x, y, nx, ny;
2573  mapstruct *m;
2574 
2575  /* We precompute some values here so that we don't have to keep
2576  * doing it over and over again.
2577  */
2578  god = find_god(determine_god(op));
2579  level = caster_level(caster, spell);
2580  range = spell->range+SP_level_range_adjust(caster, spell);
2581 
2582  for (x = op->x-range; x <= op->x+range; x++)
2583  for (y = op->y-range; y <= op->y+range; y++) {
2584  m = op->map;
2585  mflags = get_map_flags(m, &m, x, y, &nx, &ny);
2586  if (mflags&P_OUT_OF_MAP)
2587  continue;
2588 
2589  /* For most of the detections, we only detect objects above the
2590  * floor. But this is not true for show invisible.
2591  * Basically, we just go and find the top object and work
2592  * down - that is easier than working up.
2593  */
2594 
2595  last = NULL;
2596  FOR_MAP_PREPARE(m, nx, ny, tmp)
2597  last = tmp;
2598  FOR_MAP_FINISH();
2599  /* Shouldn't happen, but if there are no objects on a space, this
2600  * would happen.
2601  */
2602  if (!last)
2603  continue;
2604 
2605  done_one = 0;
2606  floor = 0;
2607  detect = NULL;
2608  tmp = last;
2610  /* show invisible */
2611  if (QUERY_FLAG(spell, FLAG_MAKE_INVIS)
2612  /* Might there be other objects that we can make visibile? */
2613  && (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) ||
2614  (tmp->type == PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)) ||
2615  tmp->type == CF_HANDLE ||
2616  tmp->type == TRAPDOOR || tmp->type == EXIT || tmp->type == HOLE ||
2617  tmp->type == BUTTON || tmp->type == TELEPORTER ||
2618  tmp->type == GATE || tmp->type == LOCKED_DOOR ||
2619  tmp->type == WEAPON || tmp->type == ALTAR || tmp->type == SIGN ||
2620  tmp->type == TRIGGER_PEDESTAL || tmp->type == SPECIAL_KEY ||
2621  tmp->type == TREASURE || tmp->type == BOOK ||
2622  tmp->type == HOLY_ALTAR))) {
2623  if (random_roll(0, level-1, op, PREFER_HIGH) > tmp->level) {
2624  tmp->invisible = 0;
2625  done_one = 1;
2626  }
2627  }
2628  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
2629  floor = 1;
2630 
2631  /* All detections below this point don't descend beneath the floor,
2632  * so just continue on. We could be clever and look at the type of
2633  * detection to completely break out if we don't care about objects beneath
2634  * the floor, but once we get to the floor, not likely a very big issue anyways.
2635  */
2636  if (floor)
2637  continue;
2638 
2639  /* I had thought about making detect magic and detect curse
2640  * show the flash the magic item like it does for detect monster.
2641  * however, if the object is within sight, this would then make it
2642  * difficult to see what object is magical/cursed, so the
2643  * effect wouldn't be as apparent.
2644  */
2645 
2646  /* detect magic */
2647  if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)
2648  && !QUERY_FLAG(tmp, FLAG_KNOWN_MAGICAL)
2649  && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)
2650  && is_magical(tmp)) {
2652  /* make runes more visible */
2653  if (tmp->type == RUNE && tmp->attacktype&AT_MAGIC)
2654  tmp->stats.Cha /= 4;
2655  done_one = 1;
2656  }
2657  /* detect monster */
2658  if (QUERY_FLAG(spell, FLAG_MONSTER)
2659  && (QUERY_FLAG(tmp, FLAG_MONSTER) || (tmp->type == PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)))) {
2660  done_one = 2;
2661  if (!detect)
2662  detect = tmp;
2663  }
2664  /* Basically, if race is set in the spell, then the creatures race must
2665  * match that. if the spell race is set to GOD, then the gods opposing
2666  * race must match.
2667  */
2668  if (spell->race
2669  && QUERY_FLAG(tmp, FLAG_MONSTER)
2670  && tmp->race
2671  && ((!strcmp(spell->race, "GOD") && god && god->slaying && strstr(god->slaying, tmp->race)) || (strstr(spell->race, tmp->race)))) {
2672  done_one = 2;
2673  if (!detect)
2674  detect = tmp;
2675  }
2676  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED)
2677  && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED)
2678  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
2680  done_one = 1;
2681  }
2682  } FOR_OB_AND_BELOW_FINISH(); /* for stack of objects on this space */
2683 
2684  /* Code here puts an effect of the spell on the space, so you can see
2685  * where the magic is.
2686  */
2687  if (done_one) {
2688  object *detect_ob;
2689  int dx = nx, dy = ny;
2690 
2691  /* if this is set, we want to copy the face */
2692  if (done_one == 2 && detect) {
2693  /*
2694  * We can't simply copy the face to a single item, because
2695  * multipart objects need to have multipart glows.
2696  * So copy the initial item, erase some properties, and use that.
2697  */
2698 
2699  object *part;
2700  int flag;
2701 
2702  dx = HEAD(detect)->x;
2703  dy = HEAD(detect)->y;
2704 
2705  detect_ob = object_create_arch(HEAD(detect)->arch);
2706  for (part = detect_ob; part != NULL; part = part->more) {
2707  if (part->arch->reference_count > 0)
2708  part->arch->reference_count++;
2709  part->last_anim = 0;
2710  part->type = spell->other_arch->clone.type;
2711  for (flag = 0; flag < 4; flag++) {
2712  part->flags[flag] = spell->other_arch->clone.flags[flag];
2713  }
2714  part->stats.food = spell->other_arch->clone.stats.food;
2715  part->last_anim = 0;
2716  part->speed = spell->other_arch->clone.speed;
2717  part->speed_left = spell->other_arch->clone.speed_left;
2718  part->move_allow = spell->other_arch->clone.move_allow;
2719  part->move_block = spell->other_arch->clone.move_block;
2720  part->move_type = spell->other_arch->clone.move_type;
2721  part->glow_radius = spell->other_arch->clone.glow_radius;
2722  part->invisible = spell->other_arch->clone.invisible;
2723  part->weight = spell->other_arch->clone.weight;
2724  part->map_layer = spell->other_arch->clone.map_layer;
2725  FREE_AND_COPY(part->name, spell->other_arch->clone.name);
2726 
2727  /* by default, the detect_ob is already animated */
2728  if (!QUERY_FLAG(detect, FLAG_ANIMATE))
2729  CLEAR_FLAG(part, FLAG_ANIMATE);
2730  }
2731  object_update_speed(detect_ob);
2732  } else
2733  detect_ob = arch_to_object(spell->other_arch);
2734 
2735  object_insert_in_map_at(detect_ob, m, op, 0, dx, dy);
2736  }
2737  } /* for processing the surrounding spaces */
2738 
2739 
2740  /* Now process objects in the players inventory if detect curse or magic */
2741  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) || QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)) {
2742  done_one = 0;
2743  FOR_INV_PREPARE(op, tmp) {
2744  if (!tmp->invisible && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)) {
2745  if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)
2746  && is_magical(tmp)
2747  && !QUERY_FLAG(tmp, FLAG_KNOWN_MAGICAL)) {
2749  if (op->type == PLAYER)
2750  esrv_send_item(op, tmp);
2751  }
2752  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED)
2753  && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED)
2754  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
2756  if (op->type == PLAYER)
2757  esrv_send_item(op, tmp);
2758  }
2759  } /* if item is not identified */
2760  } FOR_INV_FINISH(); /* for the players inventory */
2761  } /* if detect magic/curse and object is a player */
2762  return 1;
2763 }
2764 
2772 static void charge_mana_effect(object *victim, int caster_level) {
2773  /* Prevent explosions for objects without mana. Without this check, doors
2774  * will explode, too.
2775  */
2776  if (victim->stats.maxsp <= 0)
2777  return;
2778 
2780  "You feel energy course through you.");
2781 
2782  if (victim->stats.sp >= victim->stats.maxsp*2) {
2783  object *tmp;
2784 
2786  "Your head explodes!");
2787 
2788  /* Explodes a fireball centered at player */
2790  tmp->dam_modifier = random_roll(1, caster_level, victim, PREFER_LOW)/5+1;
2791  tmp->stats.maxhp = random_roll(1, caster_level, victim, PREFER_LOW)/10+2;
2792  object_insert_in_map_at(tmp, victim->map, NULL, 0, victim->x, victim->y);
2793  victim->stats.sp = 2*victim->stats.maxsp;
2794  } else if (victim->stats.sp >= victim->stats.maxsp*1.88) {
2796  "You feel like your head is going to explode.");
2797  } else if (victim->stats.sp >= victim->stats.maxsp*1.66) {
2799  "You get a splitting headache!");
2800  } else if (victim->stats.sp >= victim->stats.maxsp*1.5) {
2802  "Chaos fills your world.");
2803  confuse_living(victim, victim, 99);
2804  } else if (victim->stats.sp >= victim->stats.maxsp*1.25) {
2806  "You start hearing voices.");
2807  }
2808 }
2809 
2827 int cast_transfer(object *op, object *caster, object *spell, int dir) {
2828  object *plyr = NULL;
2829  int16_t x, y;
2830  mapstruct *m;
2831  int mflags;
2832 
2833  m = op->map;
2834  x = op->x+freearr_x[dir];
2835  y = op->y+freearr_y[dir];
2836 
2837  mflags = get_map_flags(m, &m, x, y, &x, &y);
2838  if (!(mflags&P_OUT_OF_MAP) && mflags&P_IS_ALIVE) {
2839  FOR_MAP_PREPARE(m, x, y, tmp)
2840  plyr = tmp;
2841  if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
2842  break;
2843  FOR_MAP_FINISH();
2844  }
2845 
2846  /* If we did not find a player in the specified direction, transfer
2847  * to anyone on top of us. This is used for the rune of transference mostly.
2848  */
2849  if (plyr == NULL)
2850  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp)
2851  plyr = tmp;
2852  if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
2853  break;
2854  FOR_MAP_FINISH();
2855 
2856  if (!plyr) {
2858  "There is no one there.");
2859  return 0;
2860  }
2861 
2862  /* give sp */
2863  if (spell->stats.dam > 0) {
2864  plyr->stats.sp += spell->stats.dam+SP_level_dam_adjust(caster, spell);
2865  charge_mana_effect(plyr, caster_level(caster, spell));
2866  return 1;
2867  /* suck sp away. Can't suck sp from yourself */
2868  } else if (op != plyr) {
2869  /* old dragin magic used floats. easier to just use ints and divide by 100 */
2870 
2871  int rate = -spell->stats.dam+SP_level_dam_adjust(caster, spell), sucked;
2872 
2873  if (rate > 95)
2874  rate = 95;
2875 
2876  sucked = (plyr->stats.sp*rate)/100;
2877  plyr->stats.sp -= sucked;
2878  if (QUERY_FLAG(op, FLAG_ALIVE)) {
2879  /* Player doesn't get full credit */
2880  sucked = (sucked*rate)/100;
2881  op->stats.sp += sucked;
2882  if (sucked > 0) {
2883  charge_mana_effect(op, caster_level(caster, spell));
2884  }
2885  }
2886  return 1;
2887  }
2888  return 0;
2889 }
2890 
2900 void counterspell(object *op, int dir) {
2901  object *head;
2902  int mflags;
2903  mapstruct *m;
2904  int16_t sx, sy;
2905 
2906  sx = op->x+freearr_x[dir];
2907  sy = op->y+freearr_y[dir];
2908  m = op->map;
2909  mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
2910  if (mflags&P_OUT_OF_MAP)
2911  return;
2912 
2913  FOR_MAP_PREPARE(m, sx, sy, tmp) {
2914  object *owner;
2915 
2916  /* Need to look at the head object - otherwise, if tmp
2917  * points to a monster, we don't have all the necessary
2918  * info for it.
2919  */
2920  head = HEAD(tmp);
2921 
2922  /* don't attack our own spells */
2923  owner = object_get_owner(tmp);
2924  if (owner != NULL && owner == object_get_owner(op))
2925  continue;
2926 
2927  /* Basically, if the object is magical and not counterspell,
2928  * we will more or less remove the object. Don't counterspell
2929  * monsters either.
2930  */
2931 
2932  if (head->attacktype&AT_MAGIC
2933  && !(head->attacktype&AT_COUNTERSPELL)
2934  && !QUERY_FLAG(head, FLAG_MONSTER)
2935  && (op->level > head->level)) {
2936  object_remove(head);
2937  object_free(head, 0);
2938  } else switch (head->type) {
2939  case SPELL_EFFECT:
2940  if ((op->level > head->level) && !op->stats.food && !op->speed_left) {
2941  object_remove(head);
2942  object_free(head, 0);
2943  }
2944  break;
2945 
2946  /* I really don't get this rune code that much - that
2947  * random chance seems really low.
2948  */
2949  case RUNE:
2950  if (rndm(0, 149) == 0) {
2951  head->stats.hp--; /* weaken the rune */
2952  if (!head->stats.hp) {
2953  object_remove(head);
2954  object_free(head, 0);
2955  }
2956  }
2957  break;
2958  }
2959  } FOR_MAP_FINISH();
2960 }
2961 
2976 int cast_consecrate(object *op, object *caster, object *spell) {
2977  char buf[MAX_BUF];
2978  const object *god = find_god(determine_god(op));
2979 
2980  if (!god) {
2982  "You can't consecrate anything if you don't worship a god!");
2983  return 0;
2984  }
2985 
2986  FOR_BELOW_PREPARE(op, tmp) {
2987  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
2988  break;
2989  if (tmp->type == HOLY_ALTAR) {
2990  if (tmp->level > caster_level(caster, spell)) {
2992  "You are not powerful enough to reconsecrate the %s",
2993  tmp->name);
2994  return 0;
2995  } else {
2996  /* If we got here, we are consecrating an altar */
2997  object *new_altar;
2998  size_t letter;
2999  archetype *altar_arch;
3000 
3001  snprintf(buf, MAX_BUF, "altar_");
3002  letter = strlen(buf);
3003  strncpy(buf+letter, god->name, MAX_BUF-letter);
3004  for (; letter < strlen(buf); letter++)
3005  buf[letter] = tolower(buf[letter]);
3006  altar_arch = find_archetype(buf);
3007  if (!altar_arch) {
3009  "You fail to consecrate the altar.");
3010  LOG(llevError, "cast_consecrate: can't find altar %s for god %s\n", buf, god->name);
3011  return 0;
3012  }
3013  new_altar = arch_to_object(altar_arch);
3014  new_altar->level = tmp->level;
3015  if (QUERY_FLAG(tmp, FLAG_IS_BUILDABLE))
3016  SET_FLAG(new_altar, FLAG_IS_BUILDABLE);
3017  object_insert_in_map_at(new_altar, tmp->map, tmp, INS_BELOW_ORIGINATOR, tmp->x, tmp->y);
3018  object_remove(tmp);
3020  "You consecrated the altar to %s!",
3021  god->name);
3022  return 1;
3023  }
3024  }
3025  } FOR_BELOW_FINISH();
3027  "You are not standing over an altar!");
3028  return 0;
3029 }
3030 
3054 int animate_weapon(object *op, object *caster, object *spell, int dir) {
3055  object *weapon, *tmp;
3056  char buf[MAX_BUF];
3057  int a, i;
3058  int16_t x, y;
3059  mapstruct *m;
3060  materialtype_t *mt;
3061 
3062  if (!spell->other_arch) {
3064  "Oops, program error!");
3065  LOG(llevError, "animate_weapon failed: spell %s missing other_arch!\n", spell->name);
3066  return 0;
3067  }
3068 
3069  /* exit if it's not a player using this spell. */
3070  if (op->type != PLAYER)
3071  return 0;
3072 
3073  /* if player already has a golem, abort */
3074  if (op->contr->ranges[range_golem] != NULL && op->contr->golem_count == op->contr->ranges[range_golem]->count) {
3076  return 0;
3077  }
3078 
3079  /* if no direction specified, pick one */
3080  if (!dir) {
3081  dir = object_find_free_spot(NULL, op->map, op->x, op->y, 1, 9);
3082  if ( dir == -1 ) {
3084  "There is something in the way.");
3085  return 0;
3086  }
3087  }
3088 
3089  m = op->map;
3090  x = op->x+freearr_x[dir];
3091  y = op->y+freearr_y[dir];
3092 
3093  /* if there's no place to put the golem, abort */
3094  if ((dir == -1)
3095  || (get_map_flags(m, &m, x, y, &x, &y)&P_OUT_OF_MAP)
3096  || ((spell->other_arch->clone.move_type&GET_MAP_MOVE_BLOCK(m, x, y)) == spell->other_arch->clone.move_type)) {
3098  "There is something in the way.");
3099  return 0;
3100  }
3101 
3102  /* Use the weapon marked by the player. */
3103  weapon = find_marked_object(op);
3104 
3105  if (!weapon) {
3107  "You must mark a weapon to use with this spell!");
3108  return 0;
3109  }
3110  if (spell->race && strcmp(weapon->arch->name, spell->race)) {
3112  "The spell fails to transform your weapon.");
3113  return 0;
3114  }
3115  if (weapon->type != WEAPON) {
3117  "You need to mark a weapon to animate it.");
3118  return 0;
3119  }
3120  if (QUERY_FLAG(weapon, FLAG_UNPAID)) {
3122  "You need to pay for the weapon to animate it.");
3123  return 0;
3124  }
3125  if (QUERY_FLAG(weapon, FLAG_APPLIED)) {
3126  char wn[MAX_BUF];
3127 
3128  query_name(weapon, wn, MAX_BUF);
3130  "You need to unequip %s before using it in this spell",
3131  wn);
3132  return 0;
3133  }
3134 
3135  if (weapon->nrof > 1) {
3136  tmp = object_split(weapon, 1, NULL, 0);
3137  esrv_update_item(UPD_NROF, op, weapon);
3138  weapon = tmp;
3139  }
3140 
3141  /* create the golem object */
3142  tmp = arch_to_object(spell->other_arch);
3143 
3144  /* if animated by a player, give the player control of the golem */
3145  CLEAR_FLAG(tmp, FLAG_MONSTER);
3146  SET_FLAG(tmp, FLAG_FRIENDLY);
3147  tmp->stats.exp = 0;
3148  add_friendly_object(tmp);
3149  tmp->type = GOLEM;
3150  object_set_owner(tmp, op);
3151  set_spell_skill(op, caster, spell, tmp);
3152  op->contr->ranges[range_golem] = tmp;
3153  op->contr->shoottype = range_golem;
3154  op->contr->golem_count = tmp->count;
3155 
3156  /* Give the weapon to the golem now. A bit of a hack to check the
3157  * removed flag - it should only be set if object_split() was
3158  * used above.
3159  */
3160  if (!QUERY_FLAG(weapon, FLAG_REMOVED))
3161  object_remove(weapon);
3162  object_insert_in_ob(weapon, tmp);
3163 
3164  /* To do everything necessary to let a golem use the weapon is a pain,
3165  * so instead, just set it as equipped (otherwise, we need to update
3166  * body_info, skills, etc)
3167  */
3168  SET_FLAG(tmp, FLAG_USE_WEAPON);
3169  SET_FLAG(weapon, FLAG_APPLIED);
3170  fix_object(tmp);
3171 
3172  /* There used to be 'odd' code that basically seemed to take the absolute
3173  * value of the weapon->magic an use that. IMO, that doesn't make sense -
3174  * if you're using a crappy weapon, it shouldn't be as good.
3175  */
3176 
3177  /* modify weapon's animated wc */
3178  tmp->stats.wc = tmp->stats.wc
3179  -SP_level_range_adjust(caster, spell)
3180  -5*weapon->stats.Dex
3181  -2*weapon->stats.Str
3182  -weapon->magic;
3183  if (tmp->stats.wc < -127)
3184  tmp->stats.wc = -127;
3185 
3186  /* Modify hit points for weapon */
3187  tmp->stats.maxhp = tmp->stats.maxhp
3188  +spell->duration
3189  +SP_level_duration_adjust(caster, spell)
3190  +8*weapon->magic
3191  +12*weapon->stats.Con;
3192  if (tmp->stats.maxhp < 0)
3193  tmp->stats.maxhp = 10;
3194  tmp->stats.hp = tmp->stats.maxhp;
3195 
3196  /* Modify weapon's damage */
3197  tmp->stats.dam = spell->stats.dam
3198  +SP_level_dam_adjust(caster, spell)
3199  +weapon->stats.dam
3200  +weapon->magic
3201  +5*weapon->stats.Str;
3202  if (tmp->stats.dam < 0)
3203  tmp->stats.dam = 127;
3204 
3205  /* attacktype */
3206  if (!tmp->attacktype)
3207  tmp->attacktype = AT_PHYSICAL;
3208 
3209  mt = NULL;
3210  if (op->materialname != NULL)
3211  mt = name_to_material(op->materialname);
3212  if (mt != NULL) {
3213  for (i = 0; i < NROFATTACKS; i++)
3214  tmp->resist[i] = 50-(mt->save[i]*5);
3215  a = mt->save[0];
3216  } else {
3217  for (i = 0; i < NROFATTACKS; i++)
3218  tmp->resist[i] = 5;
3219  a = 10;
3220  }
3221  /* Set weapon's immunity */
3222  tmp->resist[ATNR_CONFUSION] = 100;
3223  tmp->resist[ATNR_POISON] = 100;
3224  tmp->resist[ATNR_SLOW] = 100;
3225  tmp->resist[ATNR_PARALYZE] = 100;
3226  tmp->resist[ATNR_TURN_UNDEAD] = 100;
3227  tmp->resist[ATNR_FEAR] = 100;
3228  tmp->resist[ATNR_DEPLETE] = 100;
3229  tmp->resist[ATNR_DEATH] = 100;
3230  tmp->resist[ATNR_BLIND] = 100;
3231 
3232  /* Improve weapon's armour value according to best save vs. physical of its material */
3233 
3234  if (a > 14)
3235  a = 14;
3236  tmp->resist[ATNR_PHYSICAL] = 100-(int)((100.0-(float)tmp->resist[ATNR_PHYSICAL])/(30.0-2.0*a));
3237 
3238  /* Determine golem's speed */
3239  tmp->speed = 0.4+0.1*SP_level_range_adjust(caster, spell);
3240 
3241  if (tmp->speed > 3.33)
3242  tmp->speed = 3.33;
3243 
3244  if (!spell->race) {
3245  snprintf(buf, sizeof(buf), "animated %s", weapon->name);
3246  if (tmp->name)
3247  free_string(tmp->name);
3248  tmp->name = add_string(buf);
3249 
3250  tmp->face = weapon->face;
3251  tmp->animation_id = weapon->animation_id;
3252  tmp->anim_speed = weapon->anim_speed;
3253  tmp->last_anim = weapon->last_anim;
3254  tmp->state = weapon->state;
3255  if (QUERY_FLAG(weapon, FLAG_ANIMATE)) {
3256  SET_FLAG(tmp, FLAG_ANIMATE);
3257  } else {
3258  CLEAR_FLAG(tmp, FLAG_ANIMATE);
3259  }
3260  object_update_speed(tmp);
3261  }
3262 
3263  /* make experience increase in proportion to the strength of the summoned creature. */
3264  tmp->stats.exp *= 1+(MAX(spell->stats.maxgrace, spell->stats.sp)/caster_level(caster, spell));
3265 
3266  tmp->speed_left = -1;
3267  tmp->direction = dir;
3268  object_insert_in_map_at(tmp, m, op, 0, x, y);
3269  return 1;
3270 }
3271 
3286 int cast_change_map_lightlevel(object *op, object *caster, object *spell) {
3287  int success;
3288 
3289  if (!op->map)
3290  return 0; /* shouldnt happen */
3291 
3292  success = change_map_light(op->map, spell->stats.dam);
3293  if (!success) {
3294  if (spell->stats.dam < 0)
3296  "It can be no brighter here.");
3297  else
3299  "It can be no darker here.");
3300  }
3301  return success;
3302 }
3303 
3318 int create_aura(object *op, object *caster, object *spell) {
3319  int refresh = 0, i;
3320  object *new_aura;
3321 
3322  new_aura = arch_present_in_ob(spell->other_arch, op);
3323  if (new_aura)
3324  refresh = 1;
3325  else
3326  new_aura = arch_to_object(spell->other_arch);
3327 
3328  new_aura->duration = spell->duration+10*SP_level_duration_adjust(caster, spell);
3329  if (op->type == PLAYER)
3330  store_spell_expiry(new_aura);
3331 
3332  new_aura->stats.dam = spell->stats.dam+SP_level_dam_adjust(caster, spell);
3333 
3334  object_set_owner(new_aura, op);
3335  set_spell_skill(op, caster, spell, new_aura);
3336  new_aura->attacktype = spell->attacktype;
3337 
3338  new_aura->level = caster_level(caster, spell);
3339 
3340  /* Code below is so that auras can also provide resistances. For
3341  * example, fire shield both does damage to nearby enemies and also
3342  * provides some protection to fire. We need to use a different
3343  * FORCE object for this, as putting it in with the aura object
3344  * just puts too many meanings into that one object. Because
3345  * the duration of this force object is the same, we don't need
3346  * to set up spell expiry on it - this second object is really
3347  * an internal mechanic that should be invisible to the player.
3348  */
3349  for (i = 0; i < NROFATTACKS; i++) {
3350  if (spell->resist[i]) {
3351  int refresh1=1;
3352  object *force;
3353 
3354  force = object_present_in_ob_by_name(FORCE, spell->name, op);
3355  if (!force) {
3357  force->subtype = FORCE_CHANGE_ABILITY;
3358  free_string(force->name);
3359  force->name = add_refcount(spell->name);
3360  free_string(force->name_pl);
3361  force->name_pl = add_refcount(spell->name);
3362  refresh1=0;
3363  }
3364  force->duration = new_aura->duration;
3365  force->speed = new_aura->speed;
3366  memcpy(&force->resist, spell->resist, sizeof(spell->resist));
3367  SET_FLAG(force, FLAG_APPLIED);
3368 
3369  if (!refresh1)
3370  object_insert_in_ob(force, op);
3371  change_abil(op, new_aura);
3372  fix_object(op);
3373  break;
3374  }
3375  }
3376 
3377  if (refresh)
3379  "You recast the spell while in effect.");
3380  else
3381  object_insert_in_ob(new_aura, op);
3382  return 1;
3383 }
3384 
3400 int write_mark(object *op, object *spell, const char *msg) {
3401  char rune[HUGE_BUF];
3402  object *tmp;
3403 
3404  if (!msg || msg[0] == 0) {
3406  "Write what?");
3407  return 0;
3408  }
3409 
3410  if (strcasestr_local(msg, "endmsg")) {
3412  "Trying to cheat are we?");
3413  LOG(llevInfo, "write_rune: player %s tried to write bogus rune %s\n", op->name, msg);
3414  return 0;
3415  }
3416 
3417  if (!spell->other_arch)
3418  return 0;
3419  tmp = arch_to_object(spell->other_arch);
3420  strncpy(rune, msg, HUGE_BUF-2);
3421  rune[HUGE_BUF-2] = 0;
3422  strcat(rune, "\n");
3423  tmp->race = add_string(op->name); /*Save the owner of the rune*/
3424  object_set_msg(tmp, rune);
3425  object_insert_in_map_at(tmp, op->map, op, INS_BELOW_ORIGINATOR, op->x, op->y);
3426  return 1;
3427 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:316
char path[HUGE_BUF]
Definition: map.h:365
Definition: object.h:274
#define FLAG_KNOWN_BLESSED
Definition: define.h:379
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:219
int reference_count
Definition: object.h:475
#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:45
#define FLAG_SEE_IN_DARK
Definition: define.h:338
int apply_manual(object *op, object *tmp, int aflag)
Definition: apply.c:605
const char * determine_god(object *op)
Definition: gods.c:106
archetype * find_archetype(const char *name)
Definition: arch.c:695
#define FLAG_DAMNED
Definition: define.h:318
#define FLAG_IS_FLOOR
Definition: define.h:303
#define FLAG_UNPAID
Definition: define.h:236
int8_t ac
Definition: living.h:38
#define MOVE_WALK
Definition: define.h:407
#define UP_OBJ_FACE
Definition: object.h:519
uint8_t create_home_portals
Definition: global.h:314
#define FORCE_CHANGE_ABILITY
Definition: spells.h:145
MoveType move_type
Definition: object.h:426
#define INS_BELOW_ORIGINATOR
Definition: object.h:572
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:1411
uint8_t dam_modifier
Definition: object.h:409
Definition: object.h:185
materialtype_t * name_to_material(const char *name)
Definition: utils.c:248
const char * race
Definition: object.h:318
int is_magical(const object *op)
Definition: item.c:1238
#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:777
int caster_level(const object *caster, const object *spell)
Definition: spell_util.c:233
uint16_t attack_movement
Definition: object.h:393
void esrv_send_item(object *pl, object *op)
Definition: main.c:340
#define SET_FLAG(xyz, p)
Definition: define.h:223
sstring add_refcount(sstring str)
Definition: shstr.c:210
MoveType move_allow
Definition: object.h:428
const artifactlist * find_artifactlist(int type)
Definition: artifact.c:647
int16_t bed_x
Definition: player.h:98
object * object_find_by_type_applied(const object *who, int type)
Definition: object.c:4027
#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:622
uint16_t animation_id
Definition: object.h:418
#define MSG_TYPE_ITEM_INFO
Definition: newclient.h:641
uint8_t anim_speed
Definition: object.h:419
#define FLAG_IS_USED_UP
Definition: define.h:260
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)
uint16_t look_position
Definition: newserver.h:114
Definition: object.h:112
#define NDI_ORANGE
Definition: newclient.h:225
uint8_t last_anim
Definition: object.h:420
#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
int8_t range
Definition: object.h:407
#define ATNR_DEPLETE
Definition: attack.h:65
#define MSG_TYPE_SPELL
Definition: newclient.h:387
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:1821
#define MSG_TYPE_SPELL_FAILURE
Definition: newclient.h:628
int16_t maxgrace
Definition: living.h:45
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:343
int alchemy(object *op, object *caster, object *spell_ob)
Definition: object.h:137
void examine_monster(object *op, object *tmp, int level)
Definition: c_object.c:1364
struct treasureliststruct * randomitems
Definition: object.h:387
int cast_invisible(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:804
void pick_up(object *op, object *alt)
Definition: c_object.c:460
int cast_word_of_recall(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:916
int magic_wall(object *op, object *caster, int dir, object *spell_ob)
object clone
Definition: object.h:472
#define ATNR_SLOW
Definition: attack.h:60
int16_t duration
Definition: object.h:405
socket_struct socket
Definition: player.h:94
int16_t invisible
Definition: object.h:361
short freearr_x[SIZEOFFREE]
Definition: object.c:65
#define PREFER_LOW
Definition: define.h:602
rangetype shoottype
Definition: player.h:99
Definition: object.h:240
Definition: object.h:119
const char * slaying
Definition: object.h:319
int32_t last_sp
Definition: object.h:359
object * ranges[range_size]
Definition: player.h:103
uint8_t subtype
Definition: object.h:340
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
int64_t exp
Definition: living.h:47
#define FLAG_BLESSED
Definition: define.h:378
int cast_earth_to_dust(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:865
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:533
struct obj * above
Definition: object.h:288
Definition: object.h:157
#define object_was_destroyed(op, old_tag)
Definition: object.h:68
int remove_curse(object *op, object *caster, object *spell)
object * arch_present_in_ob(const archetype *at, const object *op)
Definition: object.c:3079
int8_t get_attr_value(const living *stats, int attr)
Definition: living.c:314
void remove_friendly_object(object *op)
Definition: friend.c:56
uint32_t path_attuned
Definition: object.h:344
#define MAX(x, y)
Definition: compat.h:20
void object_update(object *op, int action)
Definition: object.c:1262
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
int16_t sp
Definition: living.h:42
const object * find_god(const char *name)
Definition: gods.c:80
#define NDI_BLACK
Definition: newclient.h:221
#define PETMOVE
Definition: define.h:519
uint32_t hidden
Definition: player.h:132
struct obj * enemy
Definition: object.h:383
struct archt * other_arch
Definition: object.h:415
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:311
#define ATNR_CONFUSION
Definition: attack.h:54
Definition: object.h:467
char savebed_map[MAX_BUF]
Definition: player.h:97
Definition: object.h:220
#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:792
int16_t maxsp
Definition: living.h:43
int8_t Con
Definition: living.h:36
#define MIN(x, y)
Definition: compat.h:17
int change_map_light(mapstruct *m, int change)
Definition: map.c:2013
#define FLAG_REMOVED
Definition: define.h:232
int16_t hp
Definition: living.h:40
archetype * find_archetype_by_object_type_name(int type, const char *name)
Definition: arch.c:83
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:488
#define strcasestr_local
Definition: compat.h:24
void pets_control_golem(object *op, int dir)
Definition: pets.c:648
void polymorph(object *op, object *who, int level)
Definition: spell_effect.c:377
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:700
#define FLAG_UNDEAD
Definition: define.h:270
void object_set_owner(object *op, object *owner)
Definition: object.c:634
#define MSG_TYPE_SPELL_TARGET
Definition: newclient.h:633
int change_abil(object *op, object *tmp)
Definition: living.c:395
int16_t y
Definition: object.h:326
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1935
int16_t maxhp
Definition: living.h:41
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:532
static void polymorph_item(object *who, object *op, int level)
Definition: spell_effect.c:277
Definition: object.h:118
Definition: object.h:211
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:2266
int recharge(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:80
Definition: object.h:114
int is_identified(const object *op)
Definition: item.c:1359
#define MSG_TYPE_VICTIM
Definition: newclient.h:392
Definition: object.h:181
object * object_new(void)
Definition: object.c:1070
const char * name_pl
Definition: object.h:315
object * create_archetype(const char *name)
Definition: arch.c:620
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.c:95
#define FOR_OB_AND_ABOVE_FINISH()
Definition: define.h:781
#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:2709
float speed_left
Definition: object.h:329
#define MSG_TYPE_SPELL_SUCCESS
Definition: newclient.h:630
#define ATNR_PARALYZE
Definition: attack.h:61
#define INS_ON_TOP
Definition: object.h:571
#define MSG_TYPE_SPELL_HEAL
Definition: newclient.h:626
signed short int16_t
Definition: win32.h:160
const char * materialname
Definition: object.h:347
int32_t weight
Definition: object.h:366
#define MOVE_FLY_LOW
Definition: define.h:408
object * find_target_for_friendly_spell(object *op, int dir)
Definition: spell_util.c:854
void update_all_los(const mapstruct *map, int x, int y)
Definition: los.c:536
const char *const statname[NUM_STATS]
Definition: living.c:184
uint32_t tmp_invis
Definition: player.h:125
uint32_t flags[4]
Definition: object.h:417
struct mapdef * map
Definition: object.h:297
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
#define ARCH_DEPLETION
Definition: object.h:579
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
object * transport
Definition: player.h:195
#define FLAG_IDENTIFIED
Definition: define.h:261
#define FOR_INV_FINISH()
Definition: define.h:715
#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
int16_t dam
Definition: living.h:46
#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
Definition: object.h:145
#define FLAG_BLOCKSVIEW
Definition: define.h:269
int dimension_door(object *op, object *caster, object *spob, int dir)
const char * name
Definition: object.h:311
int16_t bed_y
Definition: player.h:98
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:978
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)
uint8_t state
Definition: object.h:350
int is_true_undead(object *op)
Definition: player.c:4033
struct obj * below
Definition: object.h:287
#define EXIT_PATH(xyz)
Definition: define.h:455
uint64_t price_base(const object *obj)
Definition: shop.c:70
#define INS_NO_WALK_ON
Definition: object.h:570
int16_t last_grace
Definition: object.h:360
#define SMALL_NUGGET
int8_t direction
Definition: object.h:335
uint32_t nrof
Definition: object.h:333
int8_t Cha
Definition: living.h:36
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:457
struct pl * contr
Definition: object.h:276
#define FLAG_XRAYS
Definition: define.h:301
object * find_marked_object(object *op)
Definition: c_object.c:1270
#define FREE_AND_CLEAR_STR(xyz)
Definition: global.h:206
#define ATNR_PHYSICAL
Definition: attack.h:49
static void polymorph_melt(object *who, object *op)
Definition: spell_effect.c:249
uint32_t tag_t
Definition: object.h:12
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
float speed
Definition: object.h:328
unsigned __int64 uint64_t
Definition: win32.h:167
Definition: object.h:214
#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 HEAD(op)
Definition: object.h:594
#define FLAG_WIZ
Definition: define.h:231
uint32_t golem_count
Definition: player.h:106
void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags)
Definition: treasure.c:1108
#define EXIT_Y(xyz)
Definition: define.h:458
#define MAX_BUF
Definition: define.h:35
struct obj * active_next
Definition: object.h:279
void give_artifact_abilities(object *op, const object *artifact)
Definition: artifact.c:203
object * object_create_arch(archetype *at)
Definition: arch.c:736
int cast_change_ability(object *op, object *caster, object *spell_ob, int dir, int silent)
int16_t x
Definition: object.h:326
static const char *const no_gain_msgs[NUM_STATS]
const char * skill
Definition: object.h:321
int8_t wc
Definition: living.h:37
#define tolower(C)
Definition: c_new.c:30
uint16_t difficulty
Definition: map.h:343
#define FOR_MAP_FINISH()
Definition: define.h:768
int8_t Str
Definition: living.h:36
int16_t resist[NROFATTACKS]
Definition: object.h:342
#define FLAG_KNOWN_CURSED
Definition: define.h:321
#define FLAG_CURSED
Definition: define.h:317
unsigned int uint32_t
Definition: win32.h:162
Definition: object.h:107
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:92
object * check_inv_recursive(object *op, const object *trig)
Definition: button.c:787
void store_spell_expiry(object *spell)
Definition: spell_util.c:2026
object * object_find_by_type_subtype(const object *who, int type, int subtype)
Definition: object.c:4248
#define AT_POISON
Definition: attack.h:86
#define FLAG_ANIMATE
Definition: define.h:242
#define PREFER_HIGH
Definition: define.h:601
uint32_t attacktype
Definition: object.h:343
#define FLAG_GENERATOR
Definition: define.h:248
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.c:2480
uint8_t map_layer
Definition: object.h:424
StringBuffer * describe_item(const object *op, const object *owner, int use_media_tags, StringBuffer *buf)
Definition: item.c:978
#define INS_NO_MERGE
Definition: object.h:568
Definition: object.h:122
int cast_consecrate(object *op, object *caster, object *spell)
int16_t grace
Definition: living.h:44
#define FREE_AND_COPY(sv, nv)
Definition: global.h:211
const char * invis_race
Definition: player.h:135
#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:431
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:249
tag_t count
Definition: object.h:299
living stats
Definition: object.h:369
#define FLAG_WIZCAST
Definition: define.h:290
int8_t Dex
Definition: living.h:36
struct archt * arch
Definition: object.h:414
void set_spell_skill(object *op, object *caster, object *spob, object *dest)
Definition: spell_util.c:94
Definition: object.h:207
Definition: object.h:206
#define ATNR_GODPOWER
Definition: attack.h:69
#define FLAG_IS_BUILDABLE
Definition: define.h:376
uint8_t type
Definition: object.h:339
struct Settings settings
Definition: init.c:39
void object_set_enemy(object *op, object *enemy)
Definition: object.c:712
struct archt * next
Definition: object.h:469
uint32_t weapontype
Definition: object.h:373
#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:551
#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:788
#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:1429
#define ARCH_PORTAL_FAILED
Definition: object.h:581
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
static const int32_t MAX_FOOD
Definition: define.h:477
#define GET_MAP_OB(M, X, Y)
Definition: map.h:172
int strcasecmp(const char *s1, const char *s2)
Definition: porting.c:256
int8_t glow_radius
Definition: object.h:365
#define FLAG_MONSTER
Definition: define.h:245
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.c:871
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.c:310
struct obj * inv
Definition: object.h:290
#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:757
int did_make_save(const object *op, int level, int bonus)
Definition: living.c:2276
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:761
MoveType move_block
Definition: object.h:427
int cast_create_missile(object *op, object *caster, object *spell, int dir, const char *stringarg)
Definition: spell_effect.c:499
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:4748
Definition: object.h:209
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
Definition: object.c:3433
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:626
object * item
Definition: artifact.h:15
#define LARGE_NUGGET
#define FOR_BELOW_PREPARE(op_, it_)
Definition: define.h:742
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.c:516
object * map_find_by_archetype(mapstruct *m, int x, int y, const archetype *at)
Definition: object.c:2963
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
const New_Face * face
Definition: object.h:332
#define AT_CONFUSION
Definition: attack.h:81
Definition: object.h:167
#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:4221
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
Definition: attack.c:1862
int16_t level
Definition: object.h:352
int8_t facing
Definition: object.h:336
void fix_object(object *op)
Definition: living.c:1120
EXTERN archetype * first_archetype
Definition: global.h:122
struct obj * more
Definition: object.h:295
object * arch_to_object(archetype *at)
Definition: arch.c:571
void object_update_speed(object *op)
Definition: object.c:1152
int32_t value
Definition: object.h:351
object * object_get_owner(object *op)
Definition: object.c:592
int8_t magic
Definition: object.h:349
static void polymorph_living(object *op, int level)
Definition: spell_effect.c:158
const char * name
Definition: object.h:468
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:749
#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:3057
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:708
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Definition: spell_util.c:1469
void object_remove(object *op)
Definition: object.c:1668
struct artifactstruct * next
Definition: artifact.h:18
int atnr_is_dragon_enabled(int attacknr)
Definition: player.c:95
int32_t food
Definition: living.h:48
static bool CAN_PROBE(const object *ob)
Definition: object.h:603
uint32_t count
Definition: player.h:109
Definition: object.h:224