Crossfire Server, Trunk  R20911
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 
20 #include "global.h"
21 
22 #include <assert.h>
23 #include <ctype.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "living.h"
28 #include "object.h"
29 #include "shop.h"
30 #include "sounds.h"
31 #include "spells.h"
32 #include "sproto.h"
33 
44 void cast_magic_storm(object *op, object *tmp, int lvl) {
45  if (!tmp)
46  return; /* error */
47  tmp->level = op->level;
48  tmp->range += lvl/5; /* increase the area of destruction */
49  tmp->duration += lvl/5;
50 
51  /* Put a cap on duration for this - if the player fails in their
52  * apartment, don't want it to go on so long that it kills them
53  * multiple times. Also, damage already increases with level,
54  * so don't really need to increase the duration as much either.
55  */
56  if (tmp->duration >= 40)
57  tmp->duration = 40;
58  tmp->stats.dam = lvl; /* nasty recoils! */
59  tmp->stats.maxhp = tmp->count; /* tract single parent */
60  if (tmp->stats.maxhp == 0)
61  tmp->stats.maxhp = 1;
62  object_insert_in_map_at(tmp, op->map, op, 0, op->x, op->y);
63 }
64 
79 int recharge(object *op, object *caster, object *spell_ob) {
80  object *wand, *tmp;
81  int ncharges;
82  char name[MAX_BUF];
83 
84  wand = find_marked_object(op);
85  if (wand == NULL || wand->type != WAND) {
87  "You need to mark the wand you want to recharge.");
88  return 0;
89  }
90  if (!(random_roll(0, 3, op, PREFER_HIGH))) {
91  query_name(wand, name, MAX_BUF);
93  "The %s vibrates violently, then explodes!",
94  name);
95  play_sound_map(SOUND_TYPE_ITEM, wand, 0, "explode");
96  object_remove(wand);
97  object_free2(wand, 0);
98  tmp = create_archetype("fireball");
99  tmp->stats.dam = (spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob))/10;
100  if (!tmp->stats.dam)
101  tmp->stats.dam = 1;
102  tmp->stats.hp = tmp->stats.dam/2;
103  if (tmp->stats.hp < 2)
104  tmp->stats.hp = 2;
105  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
106  return 1;
107  }
108 
109  ncharges = (spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob));
110  if (wand->inv && wand->inv->level)
111  ncharges /= wand->inv->level;
112  else {
113  query_name(wand, name, MAX_BUF);
115  "Your %s is broken.",
116  name);
117  return 0;
118  }
119  if (!ncharges)
120  ncharges = 1;
121 
122  wand->stats.food += ncharges;
123  query_name(wand, name, MAX_BUF);
125  "The %s glows with power.",
126  name);
127 
128  if (wand->arch && QUERY_FLAG(&wand->arch->clone, FLAG_ANIMATE)) {
129  SET_FLAG(wand, FLAG_ANIMATE);
130  wand->speed = wand->arch->clone.speed;
131  object_update_speed(wand);
132  }
133  return 1;
134 }
135 
136 /******************************************************************************
137  * Start of polymorph related functions.
138  *
139  * Changed around for 0.94.3 - it will now look through and use all the
140  * possible choices for objects/monsters (before it was the first 80 -
141  * arbitrary hardcoded limit in this file.) Doing this will be a bit
142  * slower however - while before, it traversed the archetypes once and
143  * stored them into an array, it will now potentially traverse it
144  * an average of 1.5 times. This is probably more costly on the polymorph
145  * item function, since it is possible a couple lookups might be needed before
146  * an item of proper value is generated.
147  */
148 
157 static void polymorph_living(object *op, int level) {
158  archetype *at;
159  int x = op->x, y = op->y, numat = 0, choice, friendly;
160  mapstruct *map = op->map;
161  object *owner;
162 
163  op = HEAD(op);
164 
165  /* High level creatures are immune, as are creatures immune to magic. Otherwise,
166  * give the creature a saving throw.
167  */
168  if (op->level >= level*2
169  || did_make_save(op, op->level, op->resist[ATNR_MAGIC]/10)
170  || (op->resist[ATNR_MAGIC] == 100))
171  return;
172 
173  object_remove(op);
174 
175  /* First, count up the number of legal matches */
176  for (at = first_archetype; at != NULL; at = at->next)
177  if ((QUERY_FLAG((&at->clone), FLAG_MONSTER) == QUERY_FLAG(op, FLAG_MONSTER))
178  && (object_find_free_spot(&at->clone, map, x, y, 0, SIZEOFFREE) != -1)) {
179  numat++;
180  }
181  if (!numat) {
182  object_insert_in_map_at(op, map, NULL, 0, x, y);
183  return; /* no valid matches? if so, return */
184  }
185 
186  /* Next make a choice, and loop through until we get to it */
187  choice = rndm(0, numat-1);
188  for (at = first_archetype; at != NULL; at = at->next)
189  if ((QUERY_FLAG((&at->clone), FLAG_MONSTER) == QUERY_FLAG(op, FLAG_MONSTER)) && (object_find_free_spot(&at->clone, map, x, y, 0, SIZEOFFREE) != -1)) {
190  if (!choice)
191  break;
192  else
193  choice--;
194  }
195 
196  /* Look through the monster. Unapply anything they have applied,
197  * and remove any spells. Note that if this is extended
198  * to players, that would need to get fixed somehow.
199  */
200  FOR_INV_PREPARE(op, tmp) {
201  if (QUERY_FLAG(tmp, FLAG_APPLIED))
202  apply_manual(op, tmp, 0);
203  if (tmp->type == SPELL) {
204  object_remove(tmp);
205  object_free2(tmp, 0);
206  }
207  } FOR_INV_FINISH();
208 
209  /* Preserve some values for the new object */
210  owner = object_get_owner(op);
211  friendly = QUERY_FLAG(op, FLAG_FRIENDLY);
212  if (friendly)
214 
215  object_copy(&(at->clone), op);
216  if (owner != NULL)
217  object_set_owner(op, owner);
218  if (friendly) {
219  SET_FLAG(op, FLAG_FRIENDLY);
220  op->attack_movement = PETMOVE;
222  } else
224 
225  /* Put the new creature on the map */
226  if ((op = object_insert_in_map_at(op, map, owner, 0, x, y)) == NULL)
227  return;
228 
229  if (HAS_RANDOM_ITEMS(op))
231 
232  /* Apply any objects. */
234 }
235 
236 
248 static void polymorph_melt(object *who, object *op) {
249  /* Not unique */
250  char name[MAX_BUF];
251 
252  query_name(op, name, MAX_BUF);
253  if (op->nrof > 1)
255  "The %s glow red, melt and evaporate!",
256  name);
257  else
259  "The %s glows red, melts and evaporates!",
260  name);
261  play_sound_map(SOUND_TYPE_ITEM, op, 0, "evaporate");
262  object_remove(op);
263  object_free2(op, 0);
264  return;
265 }
266 
276 static void polymorph_item(object *who, object *op, int level) {
277  archetype *at;
278  int max_value, difficulty, tries = 0, choice, charges = op->stats.food, numat = 0;
279  object *new_ob;
280  mapstruct *m;
281  int16_t x, y;
282 
283  /* We try and limit the maximum value of the changed object. */
284  max_value = op->value*2;
285  if (max_value > 2000*(level/10))
286  max_value = 2000*(level/10)+(max_value-2000*(level/10))/3;
287 
288  /* Look through and try to find matching items. Can't turn into something
289  * invisible. Also, if the value is too high now, it would almost
290  * certainly be too high below.
291  */
292  for (at = first_archetype; at != NULL; at = at->next) {
293  if (at->clone.type == op->type
294  && !at->clone.invisible
295  && at->clone.value > 0
296  && at->clone.value < max_value
297  && !QUERY_FLAG(&at->clone, FLAG_NO_DROP)
298  && !QUERY_FLAG(&at->clone, FLAG_STARTEQUIP))
299  numat++;
300  }
301 
302  if (!numat)
303  return;
304 
305  difficulty = op->magic*5;
306  if (difficulty < 0)
307  difficulty = 0;
308  new_ob = object_new();
309  do {
310  choice = rndm(0, numat-1);
311  for (at = first_archetype; at != NULL; at = at->next) {
312  if (at->clone.type == op->type
313  && !at->clone.invisible
314  && at->clone.value > 0
315  && at->clone.value < max_value
316  && !QUERY_FLAG(&at->clone, FLAG_NO_DROP)
317  && !QUERY_FLAG(&at->clone, FLAG_STARTEQUIP)) {
318  if (!choice)
319  break;
320  else
321  choice--;
322  }
323  }
324  object_copy(&(at->clone), new_ob);
325  fix_generated_item(new_ob, op, difficulty, FABS(op->magic), GT_ENVIRONMENT);
326  ++tries;
327  } while (new_ob->value > max_value && tries < 10);
328  if (new_ob->invisible) {
329  LOG(llevError, "polymorph_item: fix_generated_object made %s invisible?!\n", new_ob->name);
331  return;
332  }
333 
334  /* Unable to generate an acceptable item? Melt it */
335  if (tries == 10) {
336  polymorph_melt(who, op);
338  return;
339  }
340 
341  if (op->nrof && new_ob->nrof) {
342  new_ob->nrof = op->nrof;
343  /* decrease the number of items */
344  if (new_ob->nrof > 2)
345  new_ob->nrof -= rndm(0, op->nrof/2-1);
346  }
347 
348  /* We don't want rings to keep sustenance/hungry status. There are probably
349  * other cases too that should be checked.
350  */
351  if (charges && op->type != RING && op->type != FOOD)
352  op->stats.food = charges;
353 
354  x = op->x;
355  y = op->y;
356  m = op->map;
357  object_remove(op);
359  /*
360  * Don't want objects merged or re-arranged, as it then messes up the
361  * order
362  */
363  object_insert_in_map_at(new_ob, m, new_ob, INS_NO_MERGE|INS_NO_WALK_ON, x, y);
364 }
365 
376 void polymorph(object *op, object *who, int level) {
377  int tmp;
378 
379  /* Can't polymorph players right now */
380  /* polymorphing generators opens up all sorts of abuses */
381  if (op->type == PLAYER || QUERY_FLAG(op, FLAG_GENERATOR))
382  return;
383 
384  if (QUERY_FLAG(op, FLAG_MONSTER)) {
385  polymorph_living(op, level);
386  return;
387  }
388  /* If it is a living object of some other type, don't handle
389  * it now.
390  */
391  if (QUERY_FLAG(op, FLAG_ALIVE))
392  return;
393 
394  /* Don't want to morph flying arrows, etc... */
395  if (FABS(op->speed) > 0.001 && !QUERY_FLAG(op, FLAG_ANIMATE))
396  return;
397 
398  /* Do some sanity checking here. type=0 is unknown, objects
399  * without archetypes are not good. As are a few other
400  * cases.
401  */
402  if (op->type == 0
403  || op->arch == NULL
404  || QUERY_FLAG(op, FLAG_NO_PICK)
405  || op->move_block
406  || op->type == TREASURE)
407  return;
408 
409  tmp = rndm(0, 7);
410  if (tmp)
411  polymorph_item(who, op, level);
412  else
413  polymorph_melt(who, op);
414 }
415 
416 
430 int cast_polymorph(object *op, object *caster, object *spell_ob, int dir) {
431  object *tmp;
432  int range, mflags, maxrange, level;
433  mapstruct *m;
434 
435  if (dir == 0)
436  return 0;
437 
438  maxrange = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
439  level = caster_level(caster, spell_ob);
440  for (range = 1; range < maxrange; range++) {
441  int16_t x = op->x+freearr_x[dir]*range, y = op->y+freearr_y[dir]*range;
442  object *image;
443 
444  m = op->map;
445  mflags = get_map_flags(m, &m, x, y, &x, &y);
446 
447  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
448  break;
449 
450  if (GET_MAP_MOVE_BLOCK(m, x, y)&MOVE_FLY_LOW)
451  break;
452 
453  /* Get the top most object */
454  for (tmp = GET_MAP_OB(m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above)
455  ;
456 
457  /* Now start polymorphing the objects, top down */
459  /* Once we find the floor, no need to go further */
460  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
461  break;
462  polymorph(tmp, op, level);
464  image = arch_to_object(spell_ob->other_arch);
465  image->stats.food = 5;
466  image->speed_left = 0.1;
467  object_insert_in_map_at(image, m, op, 0, x, y);
468  }
469  return 1;
470 }
471 
498 int cast_create_missile(object *op, object *caster, object *spell, int dir, const char *stringarg) {
499  int missile_plus = 0, bonus_plus = 0;
500  const char *missile_name;
501  object *tmp, *missile;
502  tag_t tag;
503 
504  tmp = object_find_by_type_applied(op, BOW);
505  missile_name = tmp != NULL ? tmp->race : "arrow";
506 
507  missile_plus = spell->stats.dam+SP_level_dam_adjust(caster, spell);
508 
509  if (!strcmp(missile_name, "arrows"))
510  missile_name = "arrow";
511  else if (!strcmp(missile_name, "crossbow bolts"))
512  missile_name = "bolt";
513 
514  if (find_archetype(missile_name) == NULL) {
515  LOG(llevDebug, "Cast create_missile: could not find archetype %s\n", missile_name);
516  return 0;
517  }
518  missile = create_archetype(missile_name);
519 
520  if (stringarg) {
521  /* If it starts with a letter, presume it is a description */
522  if (isalpha(*stringarg)) {
523  artifact *al = find_artifactlist(missile->type)->items;
524 
525  for (; al != NULL; al = al->next)
526  if (!strcasecmp(al->item->name, stringarg))
527  break;
528 
529  if (!al) {
532  "No such object %ss of %s",
533  missile_name, stringarg);
534  return 0;
535  }
536  if (al->item->slaying) {
539  "You are not allowed to create %ss of %s",
540  missile_name, stringarg);
541  return 0;
542  }
543  give_artifact_abilities(missile, al->item);
544  /* These special arrows cost something extra. Don't have them also be
545  * magical - otherwise, in most cases, not enough will be created.
546  * I don't want to get into the parsing both plus and type.
547  */
548  bonus_plus = 1+(al->item->value/5);
549  missile_plus = 0;
550  } else if (atoi(stringarg) < missile_plus)
551  missile_plus = atoi(stringarg);
552  }
553  if (missile_plus > 4)
554  missile_plus = 4;
555  else if (missile_plus < -4)
556  missile_plus = -4;
557 
558  missile->nrof = spell->duration+SP_level_duration_adjust(caster, spell);
559  if (missile->nrof <= (uint32_t)3 * (missile_plus + bonus_plus)) {
562  "This item is too powerful for you to create!");
563  return 0;
564  }
565  missile->nrof -= 3*(missile_plus+bonus_plus);
566  if (missile->nrof < 1)
567  missile->nrof = 1;
568 
569  missile->magic = missile_plus;
570  /* Can't get any money for these objects */
571  missile->value = 0;
572 
573  SET_FLAG(missile, FLAG_IDENTIFIED);
574  tag = missile->count;
575 
576  if (!cast_create_obj(op, missile, dir)
577  && op->type == PLAYER
578  && !object_was_destroyed(missile, tag)) {
579  pick_up(op, missile);
580  }
581  return 1;
582 }
583 
584 
605 int cast_create_food(object *op, object *caster, object *spell_ob, int dir, const char *stringarg) {
606  int food_value;
607  archetype *at = NULL;
608  object *new_op;
609 
610  food_value = spell_ob->stats.food+50*SP_level_duration_adjust(caster, spell_ob);
611 
612  if (stringarg) {
613  at = find_archetype_by_object_type_name(FOOD, stringarg);
614  if (at == NULL)
615  at = find_archetype_by_object_type_name(DRINK, stringarg);
616  if (at == NULL || at->clone.stats.food > food_value)
617  stringarg = NULL;
618  }
619 
620  if (!stringarg) {
621  archetype *at_tmp;
622 
623  /* We try to find the archetype with the maximum food value.
624  * This removes the dependency of hard coded food values in this
625  * function, and addition of new food types is automatically added.
626  * We don't use flesh types because the weight values of those need
627  * to be altered from the donor.
628  */
629 
630  /* We assume the food items don't have multiple parts */
631  for (at_tmp = first_archetype; at_tmp != NULL; at_tmp = at_tmp->next) {
632  if (at_tmp->clone.type == FOOD || at_tmp->clone.type == DRINK) {
633  /* Basically, if the food value is something that is creatable
634  * under the limits of the spell and it is higher than
635  * the item we have now, take it instead.
636  */
637  if (at_tmp->clone.stats.food <= food_value
638  && (!at || at_tmp->clone.stats.food > at->clone.stats.food))
639  at = at_tmp;
640  }
641  }
642  }
643  /* Pretty unlikely (there are some very low food items), but you never
644  * know
645  */
646  if (!at) {
648  "You don't have enough experience to create any food.");
649  return 0;
650  }
651 
652  food_value /= at->clone.stats.food;
653  new_op = object_new();
654  object_copy(&at->clone, new_op);
655  new_op->nrof = food_value;
656 
657  new_op->value = 0;
658  if (new_op->nrof < 1)
659  new_op->nrof = 1;
660 
661  cast_create_obj(op, new_op, dir);
662  return 1;
663 }
664 
683 int probe(object *op, object *caster, object *spell_ob, int dir, int level) {
684  int r, mflags, maxrange;
685  mapstruct *m;
686 
687  if (!dir) {
688  examine_monster(op, op, level);
689  return 1;
690  }
691  maxrange = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
692  for (r = 1; r < maxrange; r++) {
693  int16_t x = op->x+r*freearr_x[dir], y = op->y+r*freearr_y[dir];
694 
695  m = op->map;
696  mflags = get_map_flags(m, &m, x, y, &x, &y);
697 
698  if (mflags&P_OUT_OF_MAP)
699  break;
700 
701  if (!QUERY_FLAG(op, FLAG_WIZCAST) && (mflags&P_NO_MAGIC)) {
703  "Something blocks your magic.");
704  return 0;
705  }
706  if (mflags&P_IS_ALIVE) {
707  FOR_MAP_PREPARE(m, x, y, tmp)
708  if (CAN_PROBE(tmp)) {
710  "You detect something.");
711  examine_monster(op, HEAD(tmp), level);
712  return 1;
713  }
714  FOR_MAP_FINISH();
715  }
716  }
718  "You detect nothing.");
719  return 1;
720 }
721 
722 
740 int makes_invisible_to(object *pl, object *mon) {
741  if (!pl->invisible)
742  return 0;
743  if (pl->type == PLAYER) {
744  /* If race isn't set, then invisible unless it is undead */
745  if (!pl->contr->invis_race) {
746  if (QUERY_FLAG(mon, FLAG_UNDEAD))
747  return 0;
748  return 1;
749  }
750  /* invis_race is set if we get here */
751  if (!strcmp(pl->contr->invis_race, "undead") && is_true_undead(mon))
752  return 1;
753  /* No race, can't be invisible to it */
754  if (!mon->race)
755  return 0;
756  if (strstr(mon->race, pl->contr->invis_race))
757  return 1;
758  /* Nothing matched above, return 0 */
759  return 0;
760  } else {
761  /* monsters are invisible to everything */
762  return 1;
763  }
764 }
765 
787 int cast_invisible(object *op, object *caster, object *spell_ob) {
788  object *tmp;
789 
790  if (op->invisible > 1000) {
792  "You can not extend the duration of your invisibility any further");
793  return 0;
794  }
795 
796  /* Remove the switch with 90% duplicate code - just handle the differences with
797  * and if statement or two.
798  */
799  op->invisible += spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
800  /* max duration */
801  if (op->invisible > 1000)
802  op->invisible = 1000;
803 
804  if (op->type == PLAYER) {
805  if (op->contr->invis_race)
807  if (spell_ob->race)
808  op->contr->invis_race = add_refcount(spell_ob->race);
809  if (QUERY_FLAG(spell_ob, FLAG_MAKE_INVIS))
810  op->contr->tmp_invis = 0;
811  else
812  op->contr->tmp_invis = 1;
813 
814  op->contr->hidden = 0;
815  }
816  if (makes_invisible_to(op, op))
818  "You can't see your hands!");
819  else
821  "You feel more transparent!");
822 
824 
825  /* Only search the active objects - only these should actually do
826  * harm to the player.
827  */
828  for (tmp = active_objects; tmp != NULL; tmp = tmp->active_next)
829  if (tmp->enemy == op)
830  object_set_enemy(tmp, NULL);
831  return 1;
832 }
833 
848 int cast_earth_to_dust(object *op, object *caster, object *spell_ob) {
849  int range, i, j, mflags;
850  int16_t sx, sy;
851  mapstruct *m;
852 
853  if (op->type != PLAYER)
854  return 0;
855 
856  range = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
857 
858  for (i = -range; i < range; i++)
859  for (j = -range; j < range; j++) {
860  sx = op->x+i;
861  sy = op->y+j;
862  m = op->map;
863  mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
864 
865  if (mflags&P_OUT_OF_MAP)
866  continue;
867 
868  /* If the space doesn't block, no wall here to remove
869  * Don't care too much what it blocks - this allows for
870  * any sort of earthwall/airwall/waterwall, etc
871  * type effects.
872  */
873  if (GET_MAP_MOVE_BLOCK(m, sx, sy)) {
874  FOR_MAP_PREPARE(m, sx, sy, tmp)
875  if (tmp && QUERY_FLAG(tmp, FLAG_TEAR_DOWN))
876  hit_player(tmp, 9998, op, AT_PHYSICAL, 0);
877  FOR_MAP_FINISH();
878  }
879  }
880  return 1;
881 }
882 
899 int cast_word_of_recall(object *op, object *caster, object *spell_ob) {
900  object *dummy;
901  int time;
902 
903  if (op->type != PLAYER)
904  return 0;
905 
908  "You feel a force starting to build up inside you.");
909  return 1;
910  }
911 
912  dummy = create_archetype(FORCE_NAME);
913  if (dummy == NULL) {
915  "Oops, program error!");
916  LOG(llevError, "cast_word_of_recall: create_archetype(force) failed!\n");
917  return 0;
918  }
919  time = spell_ob->duration-SP_level_duration_adjust(caster, spell_ob);
920  if (time < 1)
921  time = 1;
922 
923  /* value of speed really doesn't make much difference, as long as it is
924  * positive. Lower value may be useful so that the problem doesn't
925  * do anything really odd if it say a -1000 or something.
926  */
927  dummy->speed = 0.002;
928  object_update_speed(dummy);
929  dummy->speed_left = -dummy->speed*time;
930  dummy->type = SPELL_EFFECT;
931  dummy->subtype = SP_WORD_OF_RECALL;
932 
933  /* If we could take advantage of enter_player_savebed() here, it would be
934  * nice, but until the map load fails, we can't.
935  */
936  EXIT_PATH(dummy) = add_string(op->contr->savebed_map);
937  EXIT_X(dummy) = op->contr->bed_x;
938  EXIT_Y(dummy) = op->contr->bed_y;
939 
940  (void)object_insert_in_ob(dummy, op);
942  "You feel a force starting to build up inside you.");
943  return 1;
944 }
945 
961 int cast_wonder(object *op, object *caster, int dir, object *spell_ob) {
962  object *newspell;
963 
964  if (!rndm(0, 3))
965  return cast_cone(op, caster, dir, spell_ob);
966 
967  if (spell_ob->randomitems) {
968  newspell = generate_treasure(spell_ob->randomitems, caster->level);
969  if (!newspell) {
970  LOG(llevError, "cast_wonder: Unable to get a spell!\n");
971  return 0;
972  }
973  if (newspell->type != SPELL) {
974  LOG(llevError, "cast_wonder: spell returned is not a spell (%d, %s)!\n", newspell->type, newspell->name);
975  return 0;
976  }
977  /* Prevent inifinite recursion */
978  if (newspell->subtype == SP_WONDER) {
979  LOG(llevError, "cast_wonder: spell returned is another wonder spell!\n");
980  return 0;
981  }
982  return cast_spell(op, caster, dir, newspell, NULL);
983  }
984  return 1;
985 }
986 
995 int perceive_self(object *op) {
996  char *cp, buf[MAX_BUF];
998  object *tmp;
999  const object *god;
1000  int i;
1001  StringBuffer *immunity;
1002 
1003  god = find_god(determine_god(op));
1004  if (god)
1006  "You worship %s",
1007  god->name);
1008  else
1010  "You worship no god");
1011 
1012  tmp = arch_present_in_ob(at, op);
1013 
1014  cp = stringbuffer_finish(describe_item(op, op, 0, NULL));
1015 
1016  if (*cp == '\0' && tmp == NULL)
1018  "You feel very mundane");
1019  else {
1021  "You have:");
1023  cp);
1024  if (tmp != NULL) {
1025  for (i = 0; i < NUM_STATS; i++) {
1026  if (get_attr_value(&tmp->stats, i) < 0) {
1028  "Your %s is depleted by %d",
1029  statname[i], -(get_attr_value(&tmp->stats, i)));
1030  }
1031  }
1032  }
1033  }
1034  free(cp);
1035 
1036  if (op->glow_radius > 0)
1038  "You glow in the dark.");
1039 
1040  immunity = NULL;
1041  for (tmp = op->inv; tmp; tmp = tmp->below) {
1042  if (tmp->type == SIGN) {
1043  if (immunity == NULL) {
1044  immunity = stringbuffer_new();
1045  stringbuffer_append_string(immunity, "You have been exposed to: ");
1046  } else {
1047  stringbuffer_append_string(immunity, ", ");
1048  }
1049  stringbuffer_append_string(immunity, tmp->name);
1050  if (tmp->level > 100)
1051  stringbuffer_append_string(immunity, " (full immunity)");
1052  else if (tmp->level > 70)
1053  stringbuffer_append_string(immunity, " (high immunity)");
1054  else if (tmp->level > 20)
1055  stringbuffer_append_string(immunity, " (partial immunity)");
1056  }
1057  }
1058 
1059  if (immunity != NULL) {
1060  cp = stringbuffer_finish(immunity);
1062  free(cp);
1063  }
1064 
1065  if (is_dragon_pl(op)) {
1066  /* now grab the 'dragon_ability'-force from the player's inventory */
1067  tmp = object_find_by_type_and_arch_name(op, FORCE, "dragon_ability_force");
1068  if (tmp != NULL) {
1069  StringBuffer *levels = NULL;
1070  int i;
1071 
1072  if (tmp->stats.exp == 0) {
1073  snprintf(buf, sizeof(buf), "Your metabolism isn't focused on anything.");
1074  } else {
1075  snprintf(buf, sizeof(buf), "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]);
1076  }
1078  buf);
1079 
1080  for (i = 0; i < NROFATTACKS; i++) {
1081  if (atnr_is_dragon_enabled(i) && tmp->resist[i] > 0) {
1082  if (levels == NULL) {
1083  levels = stringbuffer_new();
1084  stringbuffer_append_string(levels, "Ability levels:\n");
1085  }
1086  stringbuffer_append_printf(levels, "- %s: %d\n", change_resist_msg[i], tmp->resist[i]);
1087  }
1088  }
1089 
1090  if (levels != NULL) {
1091  cp = stringbuffer_finish(levels);
1093  free(cp);
1094  }
1095  }
1096  }
1097  return 1;
1098 }
1099 
1129 int cast_create_town_portal(object *op, object *caster, object *spell, int dir) {
1130  object *dummy, *force, *old_force, *tmp;
1131  archetype *perm_portal;
1132  char portal_name [1024], portal_message [1024];
1133  int16_t exitx, exity;
1134  mapstruct *exitmap;
1135  int op_level, x, y;
1136 
1137  /* Check to see if the map the player is currently on is a per player unique
1138  * map. This can be determined in that per player unique maps have the
1139  * full pathname listed. Ignore if settings.create_home_portals is true.
1140  */
1142  if (!strncmp(op->map->path, settings.localdir, strlen(settings.localdir))) {
1144  "You can't cast that here.");
1145  return 0;
1146  }
1147  }
1148 
1149  /* Check to see if the player is on a transport */
1150  if (op->contr && op->contr->transport) {
1152  "You need to exit the transport to cast that.");
1153  return 0;
1154  }
1155 
1156  /* The first thing to do is to check if we have a marked destination
1157  * dummy is used to make a check inventory for the force
1158  */
1159  dummy = arch_to_object(spell->other_arch);
1160  if (dummy == NULL) {
1162  "Oops, program error!");
1163  LOG(llevError, "object_new failed (force in cast_create_town_portal for %s!\n", op->name);
1164  return 0;
1165  }
1166  force = check_inv_recursive(op, dummy);
1167 
1168  if (force == NULL) {
1169  /* Here we know there is no destination marked up.
1170  * We have 2 things to do:
1171  * 1. Mark the destination in the player inventory.
1172  * 2. Let the player know it worked.
1173  */
1174  free_string(dummy->name);
1175  dummy->name = add_string(op->map->path);
1176  EXIT_X(dummy) = op->x;
1177  EXIT_Y(dummy) = op->y;
1178  dummy->weapontype = op->map->last_reset_time;
1179  object_insert_in_ob(dummy, op);
1181  "You fix this place in your mind and feel that you "
1182  "can come here from anywhere.");
1183  return 1;
1184  }
1186 
1187  /* Here we know where the town portal should go to
1188  * We should kill any existing portal associated with the player.
1189  * Than we should create the 2 portals.
1190  * For each of them, we need:
1191  * - To create the portal with the name of the player+destination map
1192  * - set the owner of the town portal
1193  * - To mark the position of the portal in the player's inventory
1194  * for easier destruction.
1195  *
1196  * The mark works has follow:
1197  * slaying: Existing town portal
1198  * hp, sp : x & y of the associated portal
1199  * name : name of the portal
1200  * race : map the portal is in
1201  */
1202 
1203  /* First step: killing existing town portals */
1204  dummy = create_archetype(spell->race);
1205  if (dummy == NULL) {
1207  "Oops, program error!");
1208  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1209  return 0;
1210  }
1211  perm_portal = find_archetype(spell->slaying);
1212 
1213  /* To kill a town portal, we go trough the player's inventory,
1214  * for each marked portal in player's inventory,
1215  * -We try load the associated map (if impossible, consider the portal destructed)
1216  * -We find any portal in the specified location.
1217  * If it has the good name, we destruct it.
1218  * -We destruct the force indicating that portal.
1219  */
1220  while ((old_force = check_inv_recursive(op, dummy))) {
1221  exitx = EXIT_X(old_force);
1222  exity = EXIT_Y(old_force);
1223  LOG(llevDebug, "Trying to kill a portal in %s (%d,%d)\n", old_force->race, exitx, exity);
1224 
1225  if (!strncmp(old_force->race, settings.localdir, strlen(settings.localdir)))
1226  exitmap = ready_map_name(old_force->race, MAP_PLAYER_UNIQUE);
1227  else
1228  exitmap = ready_map_name(old_force->race, 0);
1229 
1230  if (exitmap) {
1231  tmp = map_find_by_archetype(exitmap, exitx, exity, perm_portal);
1233  if (tmp->name == old_force->name) {
1234  object_remove(tmp);
1235  object_free2(tmp, 0);
1236  break;
1237  }
1239 
1240  /* kill any opening animation there is */
1241  tmp = map_find_by_archetype(exitmap, exitx, exity, find_archetype("town_portal_open"));
1243  if (tmp->name == old_force->name) {
1244  object_remove(tmp);
1246  break;
1247  }
1249  }
1250  object_remove(old_force);
1251  object_free2(old_force, 0);
1252  LOG(llevDebug, "\n");
1253  }
1255 
1256  /* Creating the portals.
1257  * The very first thing to do is to ensure
1258  * access to the destination map.
1259  * If we can't, don't fizzle. Simply warn player.
1260  * This ensure player pays his mana for the spell
1261  * because HE is responsible for forgetting.
1262  * 'force' is the destination of the town portal, which we got
1263  * from the players inventory above.
1264  */
1265 
1266  /* Ensure exit map is loaded*/
1267  if (!strncmp(force->name, settings.localdir, strlen(settings.localdir)))
1268  exitmap = ready_map_name(force->name, MAP_PLAYER_UNIQUE);
1269  else
1270  exitmap = ready_map_name(force->name, 0);
1271 
1272  /* If we were unable to load (ex. random map deleted), warn player*/
1273  if (exitmap == NULL) {
1275  "Something strange happens. You can't remember where to go!?");
1276  object_remove(force);
1277  object_free2(force, 0);
1279  return 1;
1280  } else if (exitmap->last_reset_time != force->weapontype) {
1282  "The spell effect has expired.");
1283  object_remove(force);
1284  object_free2(force, 0);
1286  return 1;
1287  }
1288 
1289  op_level = caster_level(caster, spell);
1290  if (op_level < 15)
1291  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);
1292  else if (op_level < 30)
1293  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);
1294  else if (op_level < 60)
1295  snprintf(portal_message, 1024, "\nA shining door opens in the air in front of you, showing you the path to another place.\n");
1296  else
1297  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);
1298 
1299  /* Create a portal in front of player
1300  * dummy contain the portal and
1301  * force contain the track to kill it later
1302  */
1303 
1304  snprintf(portal_name, 1024, "%s's portal to %s", op->name, force->name);
1305  dummy = create_archetype(spell->slaying); /*The portal*/
1306  if (dummy == NULL) {
1308  "Oops, program error!");
1309  LOG(llevError, "object_new failed (perm_magic_portal) in cast_create_town_portal for %s!\n", op->name);
1310  return 0;
1311  }
1312  EXIT_PATH(dummy) = add_string(force->name);
1313  EXIT_X(dummy) = EXIT_X(force);
1314  EXIT_Y(dummy) = EXIT_Y(force);
1315  FREE_AND_COPY(dummy->name, portal_name);
1316  FREE_AND_COPY(dummy->name_pl, portal_name);
1317  object_set_msg(dummy, portal_message);
1318  dummy->race = add_string(op->name); /*Save the owner of the portal*/
1319 
1320  /* create a nice animation */
1321  tmp = create_archetype("town_portal_open");
1322  FREE_AND_COPY(tmp->name, portal_name);
1323  FREE_AND_COPY(tmp->name_pl, portal_name);
1324  object_insert_in_ob(dummy, tmp);
1325  /* and put it on the floor, when it ends the portal will be on the ground */
1326  cast_create_obj(op, tmp, 0);
1327  x = tmp->x;
1328  y = tmp->y;
1329 
1330  /* Now we need to to create a town portal marker inside the player
1331  * object, so on future castings, we can know that he has an active
1332  * town portal.
1333  */
1334  tmp = create_archetype(spell->race);
1335  if (tmp == NULL) {
1337  "Oops, program error!");
1338  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1339  return 0;
1340  }
1341  tmp->race = add_string(op->map->path);
1342  FREE_AND_COPY(tmp->name, portal_name);
1343  EXIT_X(tmp) = x;
1344  EXIT_Y(tmp) = y;
1345  object_insert_in_ob(tmp, op);
1346 
1347  /* Create a portal in the destination map
1348  * dummy contain the portal and
1349  * force the track to kill it later
1350  * the 'force' variable still contains the 'reminder' of
1351  * where this portal goes to.
1352  */
1353  snprintf(portal_name, 1024, "%s's portal to %s", op->name, op->map->path);
1354  dummy = create_archetype(spell->slaying); /*The portal*/
1355  if (dummy == NULL) {
1357  "Oops, program error!");
1358  LOG(llevError, "object_new failed (perm_magic_portal) in cast_create_town_portal for %s!\n", op->name);
1359  return 0;
1360  }
1361  EXIT_PATH(dummy) = add_string(op->map->path);
1362  EXIT_X(dummy) = op->x;
1363  EXIT_Y(dummy) = op->y;
1364  FREE_AND_COPY(dummy->name, portal_name);
1365  FREE_AND_COPY(dummy->name_pl, portal_name);
1366  object_set_msg(dummy, portal_message);
1367  dummy->race = add_string(op->name); /*Save the owner of the portal*/
1368 
1369  /* animation here too */
1370  tmp = create_archetype("town_portal_open");
1371  FREE_AND_COPY(tmp->name, portal_name);
1372  FREE_AND_COPY(tmp->name_pl, portal_name);
1373  object_insert_in_ob(dummy, tmp);
1374  /* and put it on the floor, when it ends the portal will be on the ground */
1375  object_insert_in_map_at(tmp, exitmap, op, 0, EXIT_X(force), EXIT_Y(force));
1376  x = tmp->x;
1377  y = tmp->y;
1378 
1379  /* Now we create another town portal marker that
1380  * points back to the one we just made
1381  */
1382  tmp = create_archetype(spell->race);
1383  if (tmp == NULL) {
1385  "Oops, program error!");
1386  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1387  return 0;
1388  }
1389  tmp->race = add_string(force->name);
1390  FREE_AND_COPY(tmp->name, portal_name);
1391  EXIT_X(tmp) = x;
1392  EXIT_Y(tmp) = y;
1393  object_insert_in_ob(tmp, op);
1394 
1395  /* Describe the player what happened
1396  */
1398  "You see air moving and showing you the way home.");
1399  object_remove(force); /* Delete the force inside the player*/
1400  object_free2(force, 0);
1401  return 1;
1402 }
1403 
1404 
1422 int magic_wall(object *op, object *caster, int dir, object *spell_ob) {
1423  object *tmp, *tmp2;
1424  int i, posblocked, negblocked, maxrange;
1425  int16_t x, y;
1426  mapstruct *m;
1427  const char *name;
1428  archetype *at;
1429 
1430  if (!dir) {
1431  dir = op->facing;
1432  x = op->x;
1433  y = op->y;
1434  } else {
1435  x = op->x+freearr_x[dir];
1436  y = op->y+freearr_y[dir];
1437  }
1438  m = op->map;
1439 
1440  if ((spell_ob->move_block || x != op->x || y != op->y)
1441  && (get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE)
1442  || ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) == spell_ob->move_block))) {
1444  "Something is in the way.");
1445  return 0;
1446  }
1447  if (spell_ob->other_arch) {
1448  tmp = arch_to_object(spell_ob->other_arch);
1449  } else if (spell_ob->race) {
1450  char buf1[MAX_BUF];
1451 
1452  snprintf(buf1, sizeof(buf1), spell_ob->race, dir);
1453  at = find_archetype(buf1);
1454  if (!at) {
1455  LOG(llevError, "summon_wall: Unable to find archetype %s\n", buf1);
1457  "This spell is broken.");
1458  return 0;
1459  }
1460  tmp = arch_to_object(at);
1461  } else {
1462  LOG(llevError, "magic_wall: spell %s lacks other_arch\n", spell_ob->name);
1463  return 0;
1464  }
1465 
1466  if (tmp->type == SPELL_EFFECT) {
1467  tmp->attacktype = spell_ob->attacktype;
1468  tmp->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1469  tmp->stats.dam = spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob);
1470  tmp->range = 0;
1471  } else if (QUERY_FLAG(tmp, FLAG_ALIVE)) {
1472  tmp->stats.hp = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1473  tmp->stats.maxhp = tmp->stats.hp;
1474  object_set_owner(tmp, op);
1475  set_spell_skill(op, caster, spell_ob, tmp);
1476  }
1477  if (QUERY_FLAG(spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG(tmp, FLAG_IS_USED_UP)) {
1478  tmp->stats.food = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1479  SET_FLAG(tmp, FLAG_IS_USED_UP);
1480  }
1481  if (QUERY_FLAG(spell_ob, FLAG_TEAR_DOWN)) {
1482  tmp->stats.hp = spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob);
1483  tmp->stats.maxhp = tmp->stats.hp;
1484  SET_FLAG(tmp, FLAG_TEAR_DOWN);
1485  SET_FLAG(tmp, FLAG_ALIVE);
1486  }
1487 
1488  /* This can't really hurt - if the object doesn't kill anything,
1489  * these fields just won't be used.
1490  */
1491  object_set_owner(tmp, op);
1492  set_spell_skill(op, caster, spell_ob, tmp);
1493  tmp->level = caster_level(caster, spell_ob)/2;
1494 
1495  name = tmp->name;
1496  if ((tmp = object_insert_in_map_at(tmp, m, op, 0, x, y)) == NULL) {
1498  "Something destroys your %s",
1499  name);
1500  return 0;
1501  }
1502  /* If this is a spellcasting wall, need to insert the spell object */
1503  if (tmp->other_arch && tmp->other_arch->clone.type == SPELL)
1505 
1506  /* This code causes the wall to extend some distance in
1507  * each direction, or until an obstruction is encountered.
1508  * posblocked and negblocked help determine how far the
1509  * created wall can extend, it won't go extend through
1510  * blocked spaces.
1511  */
1512  maxrange = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
1513  posblocked = 0;
1514  negblocked = 0;
1515 
1516  for (i = 1; i <= maxrange; i++) {
1517  int dir2;
1518 
1519  dir2 = (dir < 4) ? (dir+2) : dir-2;
1520 
1521  x = tmp->x+i*freearr_x[dir2];
1522  y = tmp->y+i*freearr_y[dir2];
1523  m = tmp->map;
1524 
1525  if (!(get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE))
1526  && ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block)
1527  && !posblocked) {
1528  tmp2 = object_new();
1529  object_copy(tmp, tmp2);
1530  object_insert_in_map_at(tmp2, m, op, 0, x, y);
1531  /* If this is a spellcasting wall, need to insert the spell object */
1532  if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
1534  } else
1535  posblocked = 1;
1536 
1537  x = tmp->x-i*freearr_x[dir2];
1538  y = tmp->y-i*freearr_y[dir2];
1539  m = tmp->map;
1540 
1541  if (!(get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE))
1542  && ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block)
1543  && !negblocked) {
1544  tmp2 = object_new();
1545  object_copy(tmp, tmp2);
1546  object_insert_in_map_at(tmp2, m, op, 0, x, y);
1547  if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
1549  } else
1550  negblocked = 1;
1551  }
1552 
1553  if (QUERY_FLAG(tmp, FLAG_BLOCKSVIEW))
1554  update_all_los(op->map, op->x, op->y);
1555 
1556  return 1;
1557 }
1558 
1575 int dimension_door(object *op, object *caster, object *spob, int dir) {
1576  uint32_t dist, maxdist;
1577  int mflags;
1578  mapstruct *m;
1579  int16_t sx, sy;
1580 
1581  if (op->type != PLAYER)
1582  return 0;
1583 
1584  if (!dir) {
1586  "In what direction?");
1587  return 0;
1588  }
1589 
1590  /* Given the new outdoor maps, can't let players dimension door for
1591  * ever, so put limits in.
1592  */
1593  maxdist = spob->range+SP_level_range_adjust(caster, spob);
1594 
1595  if (op->contr->count) {
1596  if (op->contr->count > maxdist) {
1598  "You can't dimension door that far!");
1599  return 0;
1600  }
1601 
1602  for (dist = 0; dist < op->contr->count; dist++) {
1603  mflags = get_map_flags(op->map, &m,
1604  op->x+freearr_x[dir]*(dist+1),
1605  op->y+freearr_y[dir]*(dist+1),
1606  &sx, &sy);
1607 
1608  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
1609  break;
1610 
1611  if ((mflags&P_BLOCKSVIEW)
1612  && OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1613  break;
1614  }
1615 
1616  if (dist < op->contr->count) {
1618  "Something blocks the magic of the spell.");
1619  op->contr->count = 0;
1620  return 0;
1621  }
1622  op->contr->count = 0;
1623 
1624  /* Remove code that puts player on random space on maps. IMO,
1625  * a lot of maps probably have areas the player should not get to,
1626  * but may not be marked as NO_MAGIC (as they may be bounded
1627  * by such squares). Also, there are probably treasure rooms and
1628  * lots of other maps that protect areas with no magic, but the
1629  * areas themselves don't contain no magic spaces.
1630  */
1631  /* This call here is really just to normalize the coordinates */
1632  mflags = get_map_flags(op->map, &m, op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist,
1633  &sx, &sy);
1634  if (mflags&P_IS_ALIVE || OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) {
1636  "You cast your spell, but nothing happens.");
1637  return 1; /* Maybe the penalty should be more severe... */
1638  }
1639  } else {
1640  /* Player didn't specify a distance, so lets see how far
1641  * we can move the player. Don't know why this stopped on
1642  * spaces that blocked the players view.
1643  */
1644 
1645  for (dist = 0; dist < maxdist; dist++) {
1646  mflags = get_map_flags(op->map, &m,
1647  op->x+freearr_x[dir]*(dist+1),
1648  op->y+freearr_y[dir]*(dist+1),
1649  &sx, &sy);
1650 
1651  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
1652  break;
1653 
1654  if ((mflags&P_BLOCKSVIEW)
1655  && OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1656  break;
1657  }
1658 
1659  /* If the destination is blocked, keep backing up until we
1660  * find a place for the player.
1661  */
1662  for (; dist > 0; dist--) {
1663  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))
1664  continue;
1665 
1666  if (!OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1667  break;
1668  }
1669  if (!dist) {
1671  "Your spell failed!");
1672  return 0;
1673  }
1674  }
1675 
1676  if (op->contr->transport && op->contr->transport->type == TRANSPORT) {
1677  ob_apply(op->contr->transport, op, 0);
1678  if (op->contr->transport) {
1680  "Your spell failed!");
1681  return 0;
1682  }
1683  }
1684 
1685  /* Actually move the player now */
1686  object_remove(op);
1687  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)
1688  return 1;
1689 
1690  if (op->type == PLAYER) {
1691  map_newmap_cmd(&op->contr->socket);
1693  }
1694  op->speed_left = -FABS(op->speed)*5; /* Freeze them for a short while */
1695  return 1;
1696 }
1697 
1698 
1711 int cast_heal(object *op, object *caster, object *spell, int dir) {
1712  object *target;
1713  archetype *at;
1714  object *poison;
1715  int heal = 0, success = 0;
1716 
1717  target = find_target_for_friendly_spell(op, dir);
1718 
1719  if (target == NULL)
1720  return 0;
1721 
1722  /* Figure out how many hp this spell might cure.
1723  * could be zero if this spell heals effects, not damage.
1724  */
1725  heal = spell->stats.dam;
1726  if (spell->stats.hp)
1727  heal += random_roll(spell->stats.hp, 6, op, PREFER_HIGH)+spell->stats.hp;
1728 
1729  if (heal) {
1730  if (target->stats.hp >= target->stats.maxhp) {
1732  "You are already fully healed.");
1733  } else {
1734  /* See how many points we actually heal. Instead of messages
1735  * based on type of spell, we instead do messages based
1736  * on amount of damage healed.
1737  */
1738  if (heal > (target->stats.maxhp-target->stats.hp))
1739  heal = target->stats.maxhp-target->stats.hp;
1740  target->stats.hp += heal;
1741 
1742  if (target->stats.hp >= target->stats.maxhp) {
1744  "You feel just fine!");
1745  } else if (heal > 50) {
1747  "Your wounds close!");
1748  } else if (heal > 25) {
1750  "Your wounds mostly close.");
1751  } else if (heal > 10) {
1753  "Your wounds start to fade.");
1754  } else {
1756  "Your wounds start to close.");
1757  }
1758  success = 1;
1759  }
1760  }
1761  if (spell->attacktype&AT_DISEASE)
1762  if (cure_disease(target, op, caster && caster->type != PLAYER ? caster->skill : spell->skill))
1763  success = 1;
1764 
1765  if (spell->attacktype&AT_POISON) {
1766  at = find_archetype("poisoning");
1767  poison = arch_present_in_ob(at, target);
1768  if (poison) {
1769  success = 1;
1771  "Your body feels cleansed");
1772  poison->stats.food = 1;
1773  }
1774  }
1775  if (spell->attacktype&AT_CONFUSION) {
1776  poison = object_present_in_ob_by_name(FORCE, "confusion", target);
1777  if (poison) {
1778  success = 1;
1780  "Your mind feels clearer");
1781  poison->duration = 1;
1782  }
1783  }
1784  if (spell->attacktype&AT_BLIND) {
1785  at = find_archetype("blindness");
1786  poison = arch_present_in_ob(at, target);
1787  if (poison) {
1788  success = 1;
1790  "Your vision begins to return.");
1791  poison->stats.food = 1;
1792  }
1793  }
1794  if (spell->last_sp && target->stats.sp < target->stats.maxsp) {
1795  target->stats.sp += spell->last_sp;
1796  if (target->stats.sp > target->stats.maxsp)
1797  target->stats.sp = target->stats.maxsp;
1798  success = 1;
1800  "Magical energies surge through your body!");
1801  }
1802  if (spell->last_grace && target->stats.grace < target->stats.maxgrace) {
1803  target->stats.grace += spell->last_grace;
1804  if (target->stats.grace > target->stats.maxgrace)
1805  target->stats.grace = target->stats.maxgrace;
1806  success = 1;
1808  "You feel redeemed with you god!");
1809  }
1810  if (spell->stats.food && target->stats.food < 999) {
1811  target->stats.food += spell->stats.food;
1812  if (target->stats.food > 999)
1813  target->stats.food = 999;
1814  success = 1;
1815  /* We could do something a bit better like the messages for healing above */
1817  "You feel your belly fill with food");
1818  }
1819 
1820  if (spell->other_arch != NULL && target->map != NULL) {
1821  object_insert_in_map_at(arch_to_object(spell->other_arch), target->map, NULL, INS_ON_TOP, target->x, target->y);
1822  }
1823 
1824  return success;
1825 }
1826 
1827 
1833 static const char *const no_gain_msgs[NUM_STATS] = {
1834  "You grow no stronger.",
1835  "You grow no more agile.",
1836  "You don't feel any healthier.",
1837  "no wis",
1838  "You are no easier to look at.",
1839  "no int",
1840  "no pow"
1841 };
1842 
1862 int cast_change_ability(object *op, object *caster, object *spell_ob, int dir, int silent) {
1863  object *tmp;
1864  object *force = NULL;
1865  int i;
1866 
1867  /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
1868  if (dir != 0) {
1869  tmp = find_target_for_friendly_spell(op, dir);
1870  } else {
1871  tmp = op;
1872  }
1873 
1874  if (tmp == NULL)
1875  return 0;
1876 
1877  /* If we've already got a force of this type, don't add a new one. */
1878  FOR_INV_PREPARE(tmp, tmp2)
1879  if (tmp2->type == FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
1880  if (tmp2->name == spell_ob->name) {
1881  force = tmp2; /* the old effect will be "refreshed" */
1882  break;
1883  } else if (spell_ob->race && spell_ob->race == tmp2->name) {
1884  if (!silent)
1886  "You can not cast %s while %s is in effect",
1887  spell_ob->name, tmp2->name_pl);
1888  return 0;
1889  }
1890  }
1891  FOR_INV_FINISH();
1892  if (force == NULL) {
1893  force = create_archetype(FORCE_NAME);
1894  force->subtype = FORCE_CHANGE_ABILITY;
1895  free_string(force->name);
1896  if (spell_ob->race)
1897  force->name = add_refcount(spell_ob->race);
1898  else
1899  force->name = add_refcount(spell_ob->name);
1900  free_string(force->name_pl);
1901  force->name_pl = add_refcount(spell_ob->name);
1902  } else {
1903  int duration;
1904 
1905  duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
1906  if (duration > force->duration) {
1907  force->duration = duration;
1909  "You recast the spell while in effect.");
1910 
1911  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
1912  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
1913  }
1914 
1915  } else {
1917  "Recasting the spell had no effect.");
1918  }
1919  return 1;
1920  }
1921  force->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
1922  if (op->type == PLAYER)
1923  store_spell_expiry(force);
1924  force->speed = 1.0;
1925  force->speed_left = -1.0;
1926  SET_FLAG(force, FLAG_APPLIED);
1927 
1928  /* Now start processing the effects. First, protections */
1929  for (i = 0; i < NROFATTACKS; i++) {
1930  if (spell_ob->resist[i]) {
1931  force->resist[i] = spell_ob->resist[i]+SP_level_dam_adjust(caster, spell_ob);
1932  if (force->resist[i] > 100)
1933  force->resist[i] = 100;
1934  }
1935  }
1936  if (spell_ob->stats.hp)
1937  force->stats.hp = spell_ob->stats.hp+SP_level_dam_adjust(caster, spell_ob);
1938 
1939  if (tmp->type == PLAYER) {
1940  /* Stat adjustment spells */
1941  for (i = 0; i < NUM_STATS; i++) {
1942  int8_t stat = get_attr_value(&spell_ob->stats, i), k, sm;
1943 
1944  if (stat) {
1945  sm = 0;
1946  for (k = 0; k < stat; k++)
1947  sm += rndm(1, 3);
1948 
1949  if ((get_attr_value(&tmp->stats, i)+sm) > (15+5*stat)) {
1950  sm = (15+5*stat)-get_attr_value(&tmp->stats, i);
1951  if (sm < 0)
1952  sm = 0;
1953  }
1954  set_attr_value(&force->stats, i, sm);
1955  if (!sm)
1957  no_gain_msgs[i]);
1958  }
1959  }
1960  }
1961 
1962  force->move_type = spell_ob->move_type;
1963 
1964  if (QUERY_FLAG(spell_ob, FLAG_SEE_IN_DARK))
1965  SET_FLAG(force, FLAG_SEE_IN_DARK);
1966 
1967  if (QUERY_FLAG(spell_ob, FLAG_XRAYS))
1968  SET_FLAG(force, FLAG_XRAYS);
1969 
1970  /* Haste/bonus speed */
1971  if (spell_ob->stats.exp) {
1972  if (op->speed > 0.5)
1973  force->stats.exp = (float)spell_ob->stats.exp/(op->speed+0.5);
1974  else
1975  force->stats.exp = spell_ob->stats.exp;
1976  }
1977 
1978  force->stats.wc = spell_ob->stats.wc;
1979  force->stats.ac = spell_ob->stats.ac;
1980  force->attacktype = spell_ob->attacktype;
1981 
1982  SET_FLAG(tmp, FLAG_NO_FIX_PLAYER); /* we don't want object_insert_in_ob() to call fix_object. */
1983  object_insert_in_ob(force, tmp);
1985  change_abil(tmp, force); /* Display any relevant messages, and call fix_object to update the player */
1986 
1987  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
1988  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
1989  }
1990 
1991  return 1;
1992 }
1993 
2010 int cast_bless(object *op, object *caster, object *spell_ob, int dir) {
2011  int i;
2012  const object *god = find_god(determine_god(op));
2013  object *force = NULL, *tmp;
2014 
2015  /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
2016  if (dir != 0) {
2017  tmp = find_target_for_friendly_spell(op, dir);
2018  } else {
2019  tmp = op;
2020  }
2021 
2022  /* If we've already got a force of this type, don't add a new one. */
2023  FOR_INV_PREPARE(tmp, tmp2)
2024  if (tmp2->type == FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
2025  if (tmp2->name == spell_ob->name) {
2026  force = tmp2; /* the old effect will be "refreshed" */
2027  break;
2028  } else if (spell_ob->race && spell_ob->race == tmp2->name) {
2030  "You can not cast %s while %s is in effect",
2031  spell_ob->name, tmp2->name_pl);
2032  return 0;
2033  }
2034  }
2035  FOR_INV_FINISH();
2036  if (force == NULL) {
2037  force = create_archetype(FORCE_NAME);
2038  force->subtype = FORCE_CHANGE_ABILITY;
2039  free_string(force->name);
2040  if (spell_ob->race)
2041  force->name = add_refcount(spell_ob->race);
2042  else
2043  force->name = add_refcount(spell_ob->name);
2044  free_string(force->name_pl);
2045  force->name_pl = add_refcount(spell_ob->name);
2046  } else {
2047  int duration;
2048 
2049  duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
2050  if (duration > force->duration) {
2051  force->duration = duration;
2053  "You recast the spell while in effect.");
2054  } else {
2056  "Recasting the spell had no effect.");
2057  }
2058  return 0;
2059  }
2060  force->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
2061  force->speed = 1.0;
2062  force->speed_left = -1.0;
2063 
2064  if (!god) {
2066  "Your blessing seems empty.");
2067  } else {
2068  /* Only give out good benefits, and put a max on it */
2069  const int16_t resist_max = spell_ob->resist[ATNR_GODPOWER];
2070  for (i = 0; i < NROFATTACKS; i++) {
2071  if (god->resist[i] > 0) {
2072  force->resist[i] = MIN(god->resist[i], resist_max);
2073  }
2074  }
2075  // Also grant appropriate amount of godpower resistance.
2076  force->resist[ATNR_GODPOWER] = spell_ob->resist[ATNR_GODPOWER];
2077 
2078  force->path_attuned |= god->path_attuned;
2079  if (spell_ob->attacktype) {
2080  force->attacktype |= god->attacktype|AT_PHYSICAL;
2081  if (god->slaying)
2082  force->slaying = add_string(god->slaying);
2083  }
2084  if (tmp != op) {
2086  "You bless %s.",
2087  tmp->name);
2089  "%s blessed you.",
2090  op->name);
2091  } else {
2093  "You are blessed by %s!",
2094  god->name);
2095  }
2096  }
2097  force->stats.wc = spell_ob->stats.wc;
2098  force->stats.ac = spell_ob->stats.ac;
2099 
2100  store_spell_expiry(force);
2101  object_insert_in_ob(force, tmp);
2102  SET_FLAG(force, FLAG_APPLIED);
2103  change_abil(tmp, force); /* To display any messages, will call fix_object() */
2104 
2105  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
2106  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
2107  }
2108  return 1;
2109 }
2110 
2111 
2112 
2113 /*
2114  * Alchemy code by Mark Wedel
2115  *
2116  * This code adds a new spell, called alchemy. Alchemy will turn
2117  * objects to gold nuggets, the value of the gold nuggets being
2118  * from 5% to 40% of that of the item itself depending on casting level.
2119  * It uses the value of the object before charisma adjustments, because
2120  * the nuggets themselves will be will be adjusted by charisma when sold.
2121  *
2122  * Large nuggets are worth 25 gp each (base). You will always get
2123  * the maximum number of large nuggets you could get.
2124  * Small nuggets are worth 1 gp each (base). You will get from 0
2125  * to the max amount of small nuggets as you could get.
2126  *
2127  * For example, if an item is worth 110 gold, you will get
2128  * 4 large nuggets, and from 0-10 small nuggets.
2129  *
2130  * There is also a chance (1:30) that you will get nothing at all
2131  * for the object. There is also a maximum weight that will be
2132  * alchemied.
2133  */
2134 
2135 #define SMALL_NUGGET "smallnugget"
2136 #define LARGE_NUGGET "largenugget"
2137 
2152 static void alchemy_object(float value_adj, object *obj, int *small_nuggets, int *large_nuggets, int *weight) {
2153  uint64_t value = price_base(obj);
2154  uint64_t small_value, large_value;
2156  /* Multiply the value of the object by value_adj, which should range
2157  * from 0.05 to 0.40. Set value to 0 instead if unpaid.
2158  */
2159  if (QUERY_FLAG(obj, FLAG_UNPAID))
2160  value = 0;
2161  else
2162  value *= value_adj;
2163 
2164  small_value = price_base(&find_archetype(SMALL_NUGGET)->clone);
2165  large_value = price_base(&find_archetype(LARGE_NUGGET)->clone);
2166 
2167  /* Give half of what value_adj says when we alchemy money (This should
2168  * hopefully make it so that it isn't worth it to alchemy money, sell
2169  * the nuggets, alchemy the gold from that, etc.
2170  */
2171  if (value && (obj->type == MONEY || obj->type == GEM))
2172  value /= 2;
2173 
2174  if ((obj->value > 0) && rndm(0, 29)) {
2175  int count;
2176 
2177  assert(large_value != 0 && small_value != 0);
2178  count = value/large_value;
2179  *large_nuggets += count;
2180  value -= (uint64_t)count*large_value;
2181  count = value/small_value;
2182  *small_nuggets += count;
2183  }
2184 
2185  /* Turn 25 small nuggets into 1 large nugget. If the value
2186  * of large nuggets is not evenly divisable by the small nugget
2187  * value, take off an extra small_nugget (Assuming small_nuggets!=0)
2188  */
2189  if (*small_nuggets*small_value >= large_value) {
2190  assert(small_value != 0);
2191  (*large_nuggets)++;
2192  *small_nuggets -= large_value/small_value;
2193  if (*small_nuggets && large_value%small_value)
2194  (*small_nuggets)--;
2195  }
2196 
2197  if (weight != NULL) {
2198  *weight += obj->weight;
2199  }
2200 
2201  object_remove(obj);
2203 }
2204 
2218 static void place_alchemy_objects(object *op, mapstruct *m, int small_nuggets, int large_nuggets, int x, int y) {
2219  object *tmp;
2220  int flag = 0;
2221 
2222  /* Put any nuggets below the player, but we can only pass this
2223  * flag if we are on the same space as the player
2224  */
2225  if (x == op->x && y == op->y && op->map == m)
2226  flag = INS_BELOW_ORIGINATOR;
2227 
2228  if (small_nuggets) {
2230  tmp-> nrof = small_nuggets;
2231  object_insert_in_map_at(tmp, m, op, flag, x, y);
2232  }
2233  if (large_nuggets) {
2235  tmp-> nrof = large_nuggets;
2236  object_insert_in_map_at(tmp, m, op, flag, x, y);
2237  }
2238 }
2239 
2254 int alchemy(object *op, object *caster, object *spell_ob) {
2255  int x, y, weight = 0, weight_max, large_nuggets, small_nuggets, mflags;
2256  int16_t nx, ny;
2257  float value_adj;
2258  mapstruct *mp;
2259 
2260  if (op->type != PLAYER)
2261  return 0;
2262 
2263  /* Put a maximum weight of items that can be alchemied. Limits the power
2264  * some, and also prevents people from alcheming every table/chair/clock
2265  * in sight
2266  */
2267  weight_max = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
2268  weight_max *= 1000;
2269 
2270  /* Set value_adj to be a multiplier for how much of the original value
2271  * will be in the nuggets. Starts at 0.05, increasing by 0.01 per casting
2272  * level, maxing out at 0.40.
2273  */
2274  value_adj = (SP_level_dam_adjust(caster, spell_ob)/100.00)+0.05;
2275 
2276  if (value_adj > 0.40)
2277  value_adj = 0.40;
2278 
2279  for (y = op->y-1; y <= op->y+1; y++) {
2280  for (x = op->x-1; x <= op->x+1; x++) {
2281  nx = x;
2282  ny = y;
2283 
2284  mp = op->map;
2285 
2286  mflags = get_map_flags(mp, &mp, nx, ny, &nx, &ny);
2287 
2288  if (mflags&(P_OUT_OF_MAP|P_NO_MAGIC))
2289  continue;
2290 
2291  /* Treat alchemy a little differently - most spell effects
2292  * use fly as the movement type - for alchemy, consider it
2293  * ground level effect.
2294  */
2295  if (GET_MAP_MOVE_BLOCK(mp, nx, ny)&MOVE_WALK)
2296  continue;
2297 
2298  small_nuggets = 0;
2299  large_nuggets = 0;
2300 
2301  FOR_MAP_PREPARE(mp, nx, ny, tmp) {
2302  if (tmp->weight > 0 && !QUERY_FLAG(tmp, FLAG_NO_PICK)
2303  && !QUERY_FLAG(tmp, FLAG_ALIVE)
2304  && !QUERY_FLAG(tmp, FLAG_IS_CAULDRON)) {
2305  if (tmp->inv) {
2306  FOR_INV_PREPARE(tmp, tmp1)
2307  if (tmp1->weight > 0 && !QUERY_FLAG(tmp1, FLAG_NO_PICK)
2308  && !QUERY_FLAG(tmp1, FLAG_ALIVE)
2309  && !QUERY_FLAG(tmp1, FLAG_IS_CAULDRON))
2310  alchemy_object(value_adj, tmp1, &small_nuggets, &large_nuggets, &weight);
2311  FOR_INV_FINISH();
2312  }
2313  alchemy_object(value_adj, tmp, &small_nuggets, &large_nuggets, &weight);
2314 
2315  if (weight > weight_max) {
2316  place_alchemy_objects(op, mp, small_nuggets, large_nuggets, nx, ny);
2317  return 1;
2318  }
2319  } /* is alchemable object */
2320  } FOR_MAP_FINISH(); /* process all objects on this space */
2321 
2322  /* Insert all the nuggets at one time. This probably saves time, but
2323  * it also prevents us from alcheming nuggets that were just created
2324  * with this spell.
2325  */
2326  place_alchemy_objects(op, mp, small_nuggets, large_nuggets, nx, ny);
2327  }
2328  }
2329 
2330  /* reset this so that if player standing on a big pile of stuff,
2331  * it is redrawn properly.
2332  */
2333  op->contr->socket.look_position = 0;
2334  return 1;
2335 }
2336 
2337 
2352 int remove_curse(object *op, object *caster, object *spell) {
2353  int success = 0, was_one = 0;
2354 
2355  FOR_INV_PREPARE(op, tmp)
2356  if (QUERY_FLAG(tmp, FLAG_APPLIED)
2357  && ((QUERY_FLAG(tmp, FLAG_CURSED) && QUERY_FLAG(spell, FLAG_CURSED))
2358  || (QUERY_FLAG(tmp, FLAG_DAMNED) && QUERY_FLAG(spell, FLAG_DAMNED)))) {
2359  was_one++;
2360  if (tmp->level <= caster_level(caster, spell)) {
2361  success++;
2362  if (QUERY_FLAG(spell, FLAG_DAMNED))
2363  CLEAR_FLAG(tmp, FLAG_DAMNED);
2364 
2365  CLEAR_FLAG(tmp, FLAG_CURSED);
2367  tmp->value = 0; /* Still can't sell it */
2368  if (op->type == PLAYER)
2369  esrv_update_item(UPD_FLAGS, op, tmp);
2370  }
2371  }
2372  FOR_INV_FINISH();
2373 
2374  if (op->type == PLAYER) {
2375  if (success) {
2377  "You feel like some of your items are looser now.");
2378  } else {
2379  if (was_one)
2381  "You failed to remove the curse.");
2382  else
2384  "You are not using any cursed items.");
2385  }
2386  }
2387  return success;
2388 }
2389 
2402 int cast_item_curse_or_curse(object *op, object *caster, object *spell_ob) {
2403  object *marked = find_marked_object(op);
2404  char name[HUGE_BUF];
2405 
2406  if (!marked) {
2408  "You need to mark an item first!");
2409  return 0;
2410  }
2411 
2412  if ((QUERY_FLAG(marked, FLAG_CURSED) && QUERY_FLAG(spell_ob, FLAG_CURSED))
2413  || (QUERY_FLAG(marked, FLAG_BLESSED) && QUERY_FLAG(spell_ob, FLAG_BLESSED))) {
2415  "The spell has no effect");
2416  return 0;
2417  }
2418 
2419  query_short_name(marked, name, HUGE_BUF);
2420  if (QUERY_FLAG(spell_ob, FLAG_CURSED)) {
2422  "Your %s emits a dark light for a few seconds.", name);
2423  SET_FLAG(marked, FLAG_CURSED);
2424  CLEAR_FLAG(marked, FLAG_KNOWN_CURSED);
2425  CLEAR_FLAG(marked, FLAG_IDENTIFIED);
2426  esrv_update_item(UPD_FLAGS, op, marked);
2427  return 1;
2428  }
2429 
2431  "Your %s glows blue for a few seconds.", name);
2432  SET_FLAG(marked, FLAG_BLESSED);
2433  SET_FLAG(marked, FLAG_KNOWN_BLESSED);
2434  SET_FLAG(marked, FLAG_STARTEQUIP);
2435  esrv_update_item(UPD_FLAGS, op, marked);
2436  return 1;
2437 }
2438 
2453 int cast_identify(object *op, object *caster, object *spell) {
2454  int success = 0, num_ident;
2455  char desc[MAX_BUF];
2456 
2457  num_ident = spell->stats.dam+SP_level_dam_adjust(caster, spell);
2458 
2459  if (num_ident < 1)
2460  num_ident = 1;
2461 
2462  FOR_INV_PREPARE(op, tmp)
2463  if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify(tmp)) {
2464  tmp = identify(tmp);
2465  if (op->type == PLAYER) {
2467  "You have %s.",
2468  ob_describe(tmp, op, desc, sizeof(desc)));
2469  if (tmp->msg) {
2471  "The item has a story:\n%s",
2472  tmp->msg);
2473  }
2474  }
2475  num_ident--;
2476  success = 1;
2477  if (!num_ident)
2478  break;
2479  }
2480  FOR_INV_FINISH();
2481  /* If all the power of the spell has been used up, don't go and identify
2482  * stuff on the floor. Only identify stuff on the floor if the spell
2483  * was not fully used.
2484  */
2485  if (num_ident) {
2486  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp)
2487  if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED)
2488  && !tmp->invisible
2489  && need_identify(tmp)) {
2490  tmp = identify(tmp);
2491  if (op->type == PLAYER) {
2493  "On the ground is %s.",
2494  ob_describe(tmp, op, desc, sizeof(desc)));
2495  if (tmp->msg) {
2497  "The item has a story:\n%s",
2498  tmp->msg);
2499  }
2501  }
2502  num_ident--;
2503  success = 1;
2504  if (!num_ident)
2505  break;
2506  }
2507  FOR_MAP_FINISH();
2508  }
2509  if (!success)
2511  "You can't reach anything unidentified.");
2512  else {
2513  spell_effect(spell, op->x, op->y, op->map, op);
2514  }
2515  return success;
2516 }
2517 
2530 int cast_detection(object *op, object *caster, object *spell) {
2531  object *tmp, *last, *detect;
2532  const object *god;
2533  int done_one, range, mflags, floor, level;
2534  int16_t x, y, nx, ny;
2535  mapstruct *m;
2536 
2537  /* We precompute some values here so that we don't have to keep
2538  * doing it over and over again.
2539  */
2540  god = find_god(determine_god(op));
2541  level = caster_level(caster, spell);
2542  range = spell->range+SP_level_range_adjust(caster, spell);
2543 
2544  for (x = op->x-range; x <= op->x+range; x++)
2545  for (y = op->y-range; y <= op->y+range; y++) {
2546  m = op->map;
2547  mflags = get_map_flags(m, &m, x, y, &nx, &ny);
2548  if (mflags&P_OUT_OF_MAP)
2549  continue;
2550 
2551  /* For most of the detections, we only detect objects above the
2552  * floor. But this is not true for show invisible.
2553  * Basically, we just go and find the top object and work
2554  * down - that is easier than working up.
2555  */
2556 
2557  last = NULL;
2558  FOR_MAP_PREPARE(m, nx, ny, tmp)
2559  last = tmp;
2560  FOR_MAP_FINISH();
2561  /* Shouldn't happen, but if there are no objects on a space, this
2562  * would happen.
2563  */
2564  if (!last)
2565  continue;
2566 
2567  done_one = 0;
2568  floor = 0;
2569  detect = NULL;
2570  tmp = last;
2572  /* show invisible */
2573  if (QUERY_FLAG(spell, FLAG_MAKE_INVIS)
2574  /* Might there be other objects that we can make visibile? */
2575  && (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) ||
2576  (tmp->type == PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)) ||
2577  tmp->type == CF_HANDLE ||
2578  tmp->type == TRAPDOOR || tmp->type == EXIT || tmp->type == HOLE ||
2579  tmp->type == BUTTON || tmp->type == TELEPORTER ||
2580  tmp->type == GATE || tmp->type == LOCKED_DOOR ||
2581  tmp->type == WEAPON || tmp->type == ALTAR || tmp->type == SIGN ||
2582  tmp->type == TRIGGER_PEDESTAL || tmp->type == SPECIAL_KEY ||
2583  tmp->type == TREASURE || tmp->type == BOOK ||
2584  tmp->type == HOLY_ALTAR))) {
2585  if (random_roll(0, level-1, op, PREFER_HIGH) > tmp->level) {
2586  tmp->invisible = 0;
2587  done_one = 1;
2588  }
2589  }
2590  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
2591  floor = 1;
2592 
2593  /* All detections below this point don't descend beneath the floor,
2594  * so just continue on. We could be clever and look at the type of
2595  * detection to completely break out if we don't care about objects beneath
2596  * the floor, but once we get to the floor, not likely a very big issue anyways.
2597  */
2598  if (floor)
2599  continue;
2600 
2601  /* I had thought about making detect magic and detect curse
2602  * show the flash the magic item like it does for detect monster.
2603  * however, if the object is within sight, this would then make it
2604  * difficult to see what object is magical/cursed, so the
2605  * effect wouldn't be as apparent.
2606  */
2607 
2608  /* detect magic */
2609  if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)
2610  && !QUERY_FLAG(tmp, FLAG_KNOWN_MAGICAL)
2611  && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)
2612  && is_magical(tmp)) {
2614  /* make runes more visible */
2615  if (tmp->type == RUNE && tmp->attacktype&AT_MAGIC)
2616  tmp->stats.Cha /= 4;
2617  done_one = 1;
2618  }
2619  /* detect monster */
2620  if (QUERY_FLAG(spell, FLAG_MONSTER)
2621  && (QUERY_FLAG(tmp, FLAG_MONSTER) || (tmp->type == PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)))) {
2622  done_one = 2;
2623  if (!detect)
2624  detect = tmp;
2625  }
2626  /* Basically, if race is set in the spell, then the creatures race must
2627  * match that. if the spell race is set to GOD, then the gods opposing
2628  * race must match.
2629  */
2630  if (spell->race
2631  && QUERY_FLAG(tmp, FLAG_MONSTER)
2632  && tmp->race
2633  && ((!strcmp(spell->race, "GOD") && god && god->slaying && strstr(god->slaying, tmp->race)) || (strstr(spell->race, tmp->race)))) {
2634  done_one = 2;
2635  if (!detect)
2636  detect = tmp;
2637  }
2638  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED)
2639  && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED)
2640  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
2642  done_one = 1;
2643  }
2644  } FOR_OB_AND_BELOW_FINISH(); /* for stack of objects on this space */
2645 
2646  /* Code here puts an effect of the spell on the space, so you can see
2647  * where the magic is.
2648  */
2649  if (done_one) {
2650  object *detect_ob;
2651  int dx = nx, dy = ny;
2652 
2653  /* if this is set, we want to copy the face */
2654  if (done_one == 2 && detect) {
2655  /*
2656  * We can't simply copy the face to a single item, because
2657  * multipart objects need to have multipart glows.
2658  * So copy the initial item, erase some properties, and use that.
2659  */
2660 
2661  object *part;
2662  int flag;
2663 
2664  dx = HEAD(detect)->x;
2665  dy = HEAD(detect)->y;
2666 
2667  detect_ob = object_create_arch(HEAD(detect)->arch);
2668  for (part = detect_ob; part != NULL; part = part->more) {
2669  if (part->arch->reference_count > 0)
2670  part->arch->reference_count++;
2671  part->last_anim = 0;
2672  part->type = spell->other_arch->clone.type;
2673  for (flag = 0; flag < 4; flag++) {
2674  part->flags[flag] = spell->other_arch->clone.flags[flag];
2675  }
2676  part->stats.food = spell->other_arch->clone.stats.food;
2677  part->last_anim = 0;
2678  part->speed = spell->other_arch->clone.speed;
2679  part->speed_left = spell->other_arch->clone.speed_left;
2680  part->move_allow = spell->other_arch->clone.move_allow;
2681  part->move_block = spell->other_arch->clone.move_block;
2682  part->move_type = spell->other_arch->clone.move_type;
2683  part->glow_radius = spell->other_arch->clone.glow_radius;
2684  part->invisible = spell->other_arch->clone.invisible;
2685  part->weight = spell->other_arch->clone.weight;
2686  part->map_layer = spell->other_arch->clone.map_layer;
2687  FREE_AND_COPY(part->name, spell->other_arch->clone.name);
2688 
2689  /* by default, the detect_ob is already animated */
2690  if (!QUERY_FLAG(detect, FLAG_ANIMATE))
2691  CLEAR_FLAG(part, FLAG_ANIMATE);
2692  }
2693  object_update_speed(detect_ob);
2694  } else
2695  detect_ob = arch_to_object(spell->other_arch);
2696 
2697  object_insert_in_map_at(detect_ob, m, op, 0, dx, dy);
2698  }
2699  } /* for processing the surrounding spaces */
2700 
2701 
2702  /* Now process objects in the players inventory if detect curse or magic */
2703  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) || QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)) {
2704  done_one = 0;
2705  FOR_INV_PREPARE(op, tmp) {
2706  if (!tmp->invisible && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)) {
2707  if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)
2708  && is_magical(tmp)
2709  && !QUERY_FLAG(tmp, FLAG_KNOWN_MAGICAL)) {
2711  if (op->type == PLAYER)
2712  esrv_send_item(op, tmp);
2713  }
2714  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED)
2715  && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED)
2716  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
2718  if (op->type == PLAYER)
2719  esrv_send_item(op, tmp);
2720  }
2721  } /* if item is not identified */
2722  } FOR_INV_FINISH(); /* for the players inventory */
2723  } /* if detect magic/curse and object is a player */
2724  return 1;
2725 }
2726 
2734 static void charge_mana_effect(object *victim, int caster_level) {
2735  /* Prevent explosions for objects without mana. Without this check, doors
2736  * will explode, too.
2737  */
2738  if (victim->stats.maxsp <= 0)
2739  return;
2740 
2742  "You feel energy course through you.");
2743 
2744  if (victim->stats.sp >= victim->stats.maxsp*2) {
2745  object *tmp;
2746 
2748  "Your head explodes!");
2749 
2750  /* Explodes a fireball centered at player */
2752  tmp->dam_modifier = random_roll(1, caster_level, victim, PREFER_LOW)/5+1;
2753  tmp->stats.maxhp = random_roll(1, caster_level, victim, PREFER_LOW)/10+2;
2754  object_insert_in_map_at(tmp, victim->map, NULL, 0, victim->x, victim->y);
2755  victim->stats.sp = 2*victim->stats.maxsp;
2756  } else if (victim->stats.sp >= victim->stats.maxsp*1.88) {
2758  "You feel like your head is going to explode.");
2759  } else if (victim->stats.sp >= victim->stats.maxsp*1.66) {
2761  "You get a splitting headache!");
2762  } else if (victim->stats.sp >= victim->stats.maxsp*1.5) {
2764  "Chaos fills your world.");
2765  confuse_living(victim, victim, 99);
2766  } else if (victim->stats.sp >= victim->stats.maxsp*1.25) {
2768  "You start hearing voices.");
2769  }
2770 }
2771 
2789 int cast_transfer(object *op, object *caster, object *spell, int dir) {
2790  object *plyr = NULL;
2791  int16_t x, y;
2792  mapstruct *m;
2793  int mflags;
2794 
2795  m = op->map;
2796  x = op->x+freearr_x[dir];
2797  y = op->y+freearr_y[dir];
2798 
2799  mflags = get_map_flags(m, &m, x, y, &x, &y);
2800  if (!(mflags&P_OUT_OF_MAP) && mflags&P_IS_ALIVE) {
2801  FOR_MAP_PREPARE(m, x, y, tmp)
2802  plyr = tmp;
2803  if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
2804  break;
2805  FOR_MAP_FINISH();
2806  }
2807 
2808  /* If we did not find a player in the specified direction, transfer
2809  * to anyone on top of us. This is used for the rune of transference mostly.
2810  */
2811  if (plyr == NULL)
2812  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp)
2813  plyr = tmp;
2814  if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
2815  break;
2816  FOR_MAP_FINISH();
2817 
2818  if (!plyr) {
2820  "There is no one there.");
2821  return 0;
2822  }
2823 
2824  /* give sp */
2825  if (spell->stats.dam > 0) {
2826  plyr->stats.sp += spell->stats.dam+SP_level_dam_adjust(caster, spell);
2827  charge_mana_effect(plyr, caster_level(caster, spell));
2828  return 1;
2829  /* suck sp away. Can't suck sp from yourself */
2830  } else if (op != plyr) {
2831  /* old dragin magic used floats. easier to just use ints and divide by 100 */
2832 
2833  int rate = -spell->stats.dam+SP_level_dam_adjust(caster, spell), sucked;
2834 
2835  if (rate > 95)
2836  rate = 95;
2837 
2838  sucked = (plyr->stats.sp*rate)/100;
2839  plyr->stats.sp -= sucked;
2840  if (QUERY_FLAG(op, FLAG_ALIVE)) {
2841  /* Player doesn't get full credit */
2842  sucked = (sucked*rate)/100;
2843  op->stats.sp += sucked;
2844  if (sucked > 0) {
2845  charge_mana_effect(op, caster_level(caster, spell));
2846  }
2847  }
2848  return 1;
2849  }
2850  return 0;
2851 }
2852 
2862 void counterspell(object *op, int dir) {
2863  object *head;
2864  int mflags;
2865  mapstruct *m;
2866  int16_t sx, sy;
2867 
2868  sx = op->x+freearr_x[dir];
2869  sy = op->y+freearr_y[dir];
2870  m = op->map;
2871  mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
2872  if (mflags&P_OUT_OF_MAP)
2873  return;
2874 
2875  FOR_MAP_PREPARE(m, sx, sy, tmp) {
2876  object *owner;
2877 
2878  /* Need to look at the head object - otherwise, if tmp
2879  * points to a monster, we don't have all the necessary
2880  * info for it.
2881  */
2882  head = HEAD(tmp);
2883 
2884  /* don't attack our own spells */
2885  owner = object_get_owner(tmp);
2886  if (owner != NULL && owner == object_get_owner(op))
2887  continue;
2888 
2889  /* Basically, if the object is magical and not counterspell,
2890  * we will more or less remove the object. Don't counterspell
2891  * monsters either.
2892  */
2893 
2894  if (head->attacktype&AT_MAGIC
2895  && !(head->attacktype&AT_COUNTERSPELL)
2896  && !QUERY_FLAG(head, FLAG_MONSTER)
2897  && (op->level > head->level)) {
2898  object_remove(head);
2899  object_free2(head, 0);
2900  } else switch (head->type) {
2901  case SPELL_EFFECT:
2902  if ((op->level > head->level) && !op->stats.food && !op->speed_left) {
2903  object_remove(head);
2904  object_free2(head, 0);
2905  }
2906  break;
2907 
2908  /* I really don't get this rune code that much - that
2909  * random chance seems really low.
2910  */
2911  case RUNE:
2912  if (rndm(0, 149) == 0) {
2913  head->stats.hp--; /* weaken the rune */
2914  if (!head->stats.hp) {
2915  object_remove(head);
2916  object_free2(head, 0);
2917  }
2918  }
2919  break;
2920  }
2921  } FOR_MAP_FINISH();
2922 }
2923 
2938 int cast_consecrate(object *op, object *caster, object *spell) {
2939  char buf[MAX_BUF];
2940  const object *god = find_god(determine_god(op));
2941 
2942  if (!god) {
2944  "You can't consecrate anything if you don't worship a god!");
2945  return 0;
2946  }
2947 
2948  FOR_BELOW_PREPARE(op, tmp) {
2949  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
2950  break;
2951  if (tmp->type == HOLY_ALTAR) {
2952  if (tmp->level > caster_level(caster, spell)) {
2954  "You are not powerful enough to reconsecrate the %s",
2955  tmp->name);
2956  return 0;
2957  } else {
2958  /* If we got here, we are consecrating an altar */
2959  object *new_altar;
2960  size_t letter;
2961  archetype *altar_arch;
2962 
2963  snprintf(buf, MAX_BUF, "altar_");
2964  letter = strlen(buf);
2965  strncpy(buf+letter, god->name, MAX_BUF-letter);
2966  for (; letter < strlen(buf); letter++)
2967  buf[letter] = tolower(buf[letter]);
2968  altar_arch = find_archetype(buf);
2969  if (!altar_arch) {
2971  "You fail to consecrate the altar.");
2972  LOG(llevError, "cast_consecrate: can't find altar %s for god %s\n", buf, god->name);
2973  return 0;
2974  }
2975  new_altar = arch_to_object(altar_arch);
2976  new_altar->level = tmp->level;
2977  if (QUERY_FLAG(tmp, FLAG_IS_BUILDABLE))
2978  SET_FLAG(new_altar, FLAG_IS_BUILDABLE);
2979  object_insert_in_map_at(new_altar, tmp->map, tmp, INS_BELOW_ORIGINATOR, tmp->x, tmp->y);
2980  object_remove(tmp);
2982  "You consecrated the altar to %s!",
2983  god->name);
2984  return 1;
2985  }
2986  }
2987  } FOR_BELOW_FINISH();
2989  "You are not standing over an altar!");
2990  return 0;
2991 }
2992 
3016 int animate_weapon(object *op, object *caster, object *spell, int dir) {
3017  object *weapon, *tmp;
3018  char buf[MAX_BUF];
3019  int a, i;
3020  int16_t x, y;
3021  mapstruct *m;
3022  materialtype_t *mt;
3023 
3024  if (!spell->other_arch) {
3026  "Oops, program error!");
3027  LOG(llevError, "animate_weapon failed: spell %s missing other_arch!\n", spell->name);
3028  return 0;
3029  }
3030 
3031  /* exit if it's not a player using this spell. */
3032  if (op->type != PLAYER)
3033  return 0;
3034 
3035  /* if player already has a golem, abort */
3036  if (op->contr->ranges[range_golem] != NULL && op->contr->golem_count == op->contr->ranges[range_golem]->count) {
3038  return 0;
3039  }
3040 
3041  /* if no direction specified, pick one */
3042  if (!dir) {
3043  dir = object_find_free_spot(NULL, op->map, op->x, op->y, 1, 9);
3044  assert(dir != -1);
3045  }
3046 
3047  m = op->map;
3048  x = op->x+freearr_x[dir];
3049  y = op->y+freearr_y[dir];
3050 
3051  /* if there's no place to put the golem, abort */
3052  if ((dir == -1)
3053  || (get_map_flags(m, &m, x, y, &x, &y)&P_OUT_OF_MAP)
3054  || ((spell->other_arch->clone.move_type&GET_MAP_MOVE_BLOCK(m, x, y)) == spell->other_arch->clone.move_type)) {
3056  "There is something in the way.");
3057  return 0;
3058  }
3059 
3060  /* Use the weapon marked by the player. */
3061  weapon = find_marked_object(op);
3062 
3063  if (!weapon) {
3065  "You must mark a weapon to use with this spell!");
3066  return 0;
3067  }
3068  if (spell->race && strcmp(weapon->arch->name, spell->race)) {
3070  "The spell fails to transform your weapon.");
3071  return 0;
3072  }
3073  if (weapon->type != WEAPON) {
3075  "You need to mark a weapon to animate it.");
3076  return 0;
3077  }
3078  if (QUERY_FLAG(weapon, FLAG_UNPAID)) {
3080  "You need to pay for the weapon to animate it.");
3081  return 0;
3082  }
3083  if (QUERY_FLAG(weapon, FLAG_APPLIED)) {
3084  char wn[MAX_BUF];
3085 
3086  query_name(weapon, wn, MAX_BUF);
3088  "You need to unequip %s before using it in this spell",
3089  wn);
3090  return 0;
3091  }
3092 
3093  if (weapon->nrof > 1) {
3094  tmp = object_split(weapon, 1, NULL, 0);
3095  esrv_update_item(UPD_NROF, op, weapon);
3096  weapon = tmp;
3097  }
3098 
3099  /* create the golem object */
3100  tmp = arch_to_object(spell->other_arch);
3101 
3102  /* if animated by a player, give the player control of the golem */
3103  CLEAR_FLAG(tmp, FLAG_MONSTER);
3104  SET_FLAG(tmp, FLAG_FRIENDLY);
3105  tmp->stats.exp = 0;
3106  add_friendly_object(tmp);
3107  tmp->type = GOLEM;
3108  object_set_owner(tmp, op);
3109  set_spell_skill(op, caster, spell, tmp);
3110  op->contr->ranges[range_golem] = tmp;
3111  op->contr->shoottype = range_golem;
3112  op->contr->golem_count = tmp->count;
3113 
3114  /* Give the weapon to the golem now. A bit of a hack to check the
3115  * removed flag - it should only be set if object_split() was
3116  * used above.
3117  */
3118  if (!QUERY_FLAG(weapon, FLAG_REMOVED))
3119  object_remove(weapon);
3120  object_insert_in_ob(weapon, tmp);
3121 
3122  /* To do everything necessary to let a golem use the weapon is a pain,
3123  * so instead, just set it as equipped (otherwise, we need to update
3124  * body_info, skills, etc)
3125  */
3126  SET_FLAG(tmp, FLAG_USE_WEAPON);
3127  SET_FLAG(weapon, FLAG_APPLIED);
3128  fix_object(tmp);
3129 
3130  /* There used to be 'odd' code that basically seemed to take the absolute
3131  * value of the weapon->magic an use that. IMO, that doesn't make sense -
3132  * if you're using a crappy weapon, it shouldn't be as good.
3133  */
3134 
3135  /* modify weapon's animated wc */
3136  tmp->stats.wc = tmp->stats.wc
3137  -SP_level_range_adjust(caster, spell)
3138  -5*weapon->stats.Dex
3139  -2*weapon->stats.Str
3140  -weapon->magic;
3141  if (tmp->stats.wc < -127)
3142  tmp->stats.wc = -127;
3143 
3144  /* Modify hit points for weapon */
3145  tmp->stats.maxhp = tmp->stats.maxhp
3146  +spell->duration
3147  +SP_level_duration_adjust(caster, spell)
3148  +8*weapon->magic
3149  +12*weapon->stats.Con;
3150  if (tmp->stats.maxhp < 0)
3151  tmp->stats.maxhp = 10;
3152  tmp->stats.hp = tmp->stats.maxhp;
3153 
3154  /* Modify weapon's damage */
3155  tmp->stats.dam = spell->stats.dam
3156  +SP_level_dam_adjust(caster, spell)
3157  +weapon->stats.dam
3158  +weapon->magic
3159  +5*weapon->stats.Str;
3160  if (tmp->stats.dam < 0)
3161  tmp->stats.dam = 127;
3162 
3163  /* attacktype */
3164  if (!tmp->attacktype)
3165  tmp->attacktype = AT_PHYSICAL;
3166 
3167  mt = NULL;
3168  if (op->materialname != NULL)
3169  mt = name_to_material(op->materialname);
3170  if (mt != NULL) {
3171  for (i = 0; i < NROFATTACKS; i++)
3172  tmp->resist[i] = 50-(mt->save[i]*5);
3173  a = mt->save[0];
3174  } else {
3175  for (i = 0; i < NROFATTACKS; i++)
3176  tmp->resist[i] = 5;
3177  a = 10;
3178  }
3179  /* Set weapon's immunity */
3180  tmp->resist[ATNR_CONFUSION] = 100;
3181  tmp->resist[ATNR_POISON] = 100;
3182  tmp->resist[ATNR_SLOW] = 100;
3183  tmp->resist[ATNR_PARALYZE] = 100;
3184  tmp->resist[ATNR_TURN_UNDEAD] = 100;
3185  tmp->resist[ATNR_FEAR] = 100;
3186  tmp->resist[ATNR_DEPLETE] = 100;
3187  tmp->resist[ATNR_DEATH] = 100;
3188  tmp->resist[ATNR_BLIND] = 100;
3189 
3190  /* Improve weapon's armour value according to best save vs. physical of its material */
3191 
3192  if (a > 14)
3193  a = 14;
3194  tmp->resist[ATNR_PHYSICAL] = 100-(int)((100.0-(float)tmp->resist[ATNR_PHYSICAL])/(30.0-2.0*a));
3195 
3196  /* Determine golem's speed */
3197  tmp->speed = 0.4+0.1*SP_level_range_adjust(caster, spell);
3198 
3199  if (tmp->speed > 3.33)
3200  tmp->speed = 3.33;
3201 
3202  if (!spell->race) {
3203  snprintf(buf, sizeof(buf), "animated %s", weapon->name);
3204  if (tmp->name)
3205  free_string(tmp->name);
3206  tmp->name = add_string(buf);
3207 
3208  tmp->face = weapon->face;
3209  tmp->animation_id = weapon->animation_id;
3210  tmp->anim_speed = weapon->anim_speed;
3211  tmp->last_anim = weapon->last_anim;
3212  tmp->state = weapon->state;
3213  if (QUERY_FLAG(weapon, FLAG_ANIMATE)) {
3214  SET_FLAG(tmp, FLAG_ANIMATE);
3215  } else {
3216  CLEAR_FLAG(tmp, FLAG_ANIMATE);
3217  }
3218  object_update_speed(tmp);
3219  }
3220 
3221  /* make experience increase in proportion to the strength of the summoned creature. */
3222  tmp->stats.exp *= 1+(MAX(spell->stats.maxgrace, spell->stats.sp)/caster_level(caster, spell));
3223 
3224  tmp->speed_left = -1;
3225  tmp->direction = dir;
3226  object_insert_in_map_at(tmp, m, op, 0, x, y);
3227  return 1;
3228 }
3229 
3244 int cast_change_map_lightlevel(object *op, object *caster, object *spell) {
3245  int success;
3246 
3247  if (!op->map)
3248  return 0; /* shouldnt happen */
3249 
3250  success = change_map_light(op->map, spell->stats.dam);
3251  if (!success) {
3252  if (spell->stats.dam < 0)
3254  "It can be no brighter here.");
3255  else
3257  "It can be no darker here.");
3258  }
3259  return success;
3260 }
3261 
3276 int create_aura(object *op, object *caster, object *spell) {
3277  int refresh = 0, i;
3278  object *new_aura;
3279 
3280  new_aura = arch_present_in_ob(spell->other_arch, op);
3281  if (new_aura)
3282  refresh = 1;
3283  else
3284  new_aura = arch_to_object(spell->other_arch);
3285 
3286  new_aura->duration = spell->duration+10*SP_level_duration_adjust(caster, spell);
3287  if (op->type == PLAYER)
3288  store_spell_expiry(new_aura);
3289 
3290  new_aura->stats.dam = spell->stats.dam+SP_level_dam_adjust(caster, spell);
3291 
3292  object_set_owner(new_aura, op);
3293  set_spell_skill(op, caster, spell, new_aura);
3294  new_aura->attacktype = spell->attacktype;
3295 
3296  new_aura->level = caster_level(caster, spell);
3297 
3298  /* Code below is so that auras can also provide resistances. For
3299  * example, fire shield both does damage to nearby enemies and also
3300  * provides some protection to fire. We need to use a different
3301  * FORCE object for this, as putting it in with the aura object
3302  * just puts too many meanings into that one object. Because
3303  * the duration of this force object is the same, we don't need
3304  * to set up spell expiry on it - this second object is really
3305  * an internal mechanic that should be invisible to the player.
3306  */
3307  for (i = 0; i < NROFATTACKS; i++) {
3308  if (spell->resist[i]) {
3309  int refresh1=1;
3310  object *force;
3311 
3312  force = object_present_in_ob_by_name(FORCE, spell->name, op);
3313  if (!force) {
3315  force->subtype = FORCE_CHANGE_ABILITY;
3316  free_string(force->name);
3317  force->name = add_refcount(spell->name);
3318  free_string(force->name_pl);
3319  force->name_pl = add_refcount(spell->name);
3320  refresh1=0;
3321  }
3322  force->duration = new_aura->duration;
3323  force->speed = new_aura->speed;
3324  memcpy(&force->resist, spell->resist, sizeof(spell->resist));
3325  SET_FLAG(force, FLAG_APPLIED);
3326 
3327  if (!refresh1)
3328  object_insert_in_ob(force, op);
3329  change_abil(op, new_aura);
3330  fix_object(op);
3331  break;
3332  }
3333  }
3334 
3335  if (refresh)
3337  "You recast the spell while in effect.");
3338  else
3339  object_insert_in_ob(new_aura, op);
3340  return 1;
3341 }
3342 
3358 int write_mark(object *op, object *spell, const char *msg) {
3359  char rune[HUGE_BUF];
3360  object *tmp;
3361 
3362  if (!msg || msg[0] == 0) {
3364  "Write what?");
3365  return 0;
3366  }
3367 
3368  if (strcasestr_local(msg, "endmsg")) {
3370  "Trying to cheat are we?");
3371  LOG(llevInfo, "write_rune: player %s tried to write bogus rune %s\n", op->name, msg);
3372  return 0;
3373  }
3374 
3375  if (!spell->other_arch)
3376  return 0;
3377  tmp = arch_to_object(spell->other_arch);
3378  strncpy(rune, msg, HUGE_BUF-2);
3379  rune[HUGE_BUF-2] = 0;
3380  strcat(rune, "\n");
3381  tmp->race = add_string(op->name); /*Save the owner of the rune*/
3382  object_set_msg(tmp, rune);
3383  object_insert_in_map_at(tmp, op->map, op, INS_BELOW_ORIGINATOR, op->x, op->y);
3384  return 1;
3385 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:315
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:218
int reference_count
Definition: object.h:473
#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:44
#define FLAG_SEE_IN_DARK
Definition: define.h:338
int apply_manual(object *op, object *tmp, int aflag)
Definition: apply.c:510
const char * determine_god(object *op)
Definition: gods.c:106
archetype * find_archetype(const char *name)
Definition: arch.c:692
#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:37
#define MOVE_WALK
Definition: define.h:407
#define UP_OBJ_FACE
Definition: object.h:519
uint8_t create_home_portals
Definition: global.h:308
#define FORCE_CHANGE_ABILITY
Definition: spells.h:145
MoveType move_type
Definition: object.h:424
#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
uint8_t dam_modifier
Definition: object.h:407
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:1243
#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:774
int caster_level(const object *caster, const object *spell)
Definition: spell_util.c:233
uint16_t attack_movement
Definition: object.h:391
void esrv_send_item(object *pl, object *op)
Definition: main.c:339
#define SET_FLAG(xyz, p)
Definition: define.h:223
sstring add_refcount(sstring str)
Definition: shstr.c:210
MoveType move_allow
Definition: object.h:426
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:3977
#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:605
uint16_t animation_id
Definition: object.h:416
#define MSG_TYPE_ITEM_INFO
Definition: newclient.h:641
uint8_t anim_speed
Definition: object.h:417
#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:126
Definition: object.h:112
#define NDI_ORANGE
Definition: newclient.h:225
uint8_t last_anim
Definition: object.h:418
#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:405
#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:1817
#define MSG_TYPE_SPELL_FAILURE
Definition: newclient.h:628
int16_t maxgrace
Definition: living.h:44
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:342
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:1350
struct treasureliststruct * randomitems
Definition: object.h:385
int cast_invisible(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:787
void pick_up(object *op, object *alt)
Definition: c_object.c:446
int cast_word_of_recall(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:899
int magic_wall(object *op, object *caster, int dir, object *spell_ob)
object clone
Definition: object.h:470
#define ATNR_SLOW
Definition: attack.h:60
int16_t duration
Definition: object.h:403
socket_struct socket
Definition: player.h:94
int16_t invisible
Definition: object.h:360
short freearr_x[SIZEOFFREE]
Definition: object.c:65
#define PREFER_LOW
Definition: define.h:600
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:358
object * ranges[range_size]
Definition: player.h:103
uint8_t subtype
Definition: object.h:339
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:328
int64_t exp
Definition: living.h:46
#define FLAG_BLESSED
Definition: define.h:378
int cast_earth_to_dust(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:848
#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:3061
int8_t get_attr_value(const living *stats, int attr)
Definition: living.c:313
void remove_friendly_object(object *op)
Definition: friend.c:56
uint32_t path_attuned
Definition: object.h:343
#define MAX(x, y)
Definition: compat.h:20
void object_update(object *op, int action)
Definition: object.c:1239
method_ret ob_apply(object *op, object *applier, int aflags)
Definition: ob_methods.c:42
#define FLAG_TEAR_DOWN
Definition: define.h:279
#define AT_BLIND
Definition: attack.h:98
int16_t sp
Definition: living.h:41
const object * find_god(const char *name)
Definition: gods.c:80
#define NDI_BLACK
Definition: newclient.h:221
#define PETMOVE
Definition: define.h:517
uint32_t hidden
Definition: player.h:132
struct obj * enemy
Definition: object.h:381
struct archt * other_arch
Definition: object.h:413
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:310
#define ATNR_CONFUSION
Definition: attack.h:54
Definition: object.h:465
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:789
int16_t maxsp
Definition: living.h:42
int8_t Con
Definition: living.h:35
#define MIN(x, y)
Definition: compat.h:17
int change_map_light(mapstruct *m, int change)
Definition: map.c:2009
#define FLAG_REMOVED
Definition: define.h:232
int16_t hp
Definition: living.h:39
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:490
#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:376
int rndm(int min, int max)
Definition: utils.c:162
void map_newmap_cmd(socket_struct *ns)
Definition: request.c:615
int probe(object *op, object *caster, object *spell_ob, int dir, int level)
Definition: spell_effect.c:683
#define FLAG_UNDEAD
Definition: define.h:270
void object_set_owner(object *op, object *owner)
Definition: object.c:601
#define MSG_TYPE_SPELL_TARGET
Definition: newclient.h:633
int change_abil(object *op, object *tmp)
Definition: living.c:394
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:1921
int16_t maxhp
Definition: living.h:40
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:532
static void polymorph_item(object *who, object *op, int level)
Definition: spell_effect.c:276
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:2258
int recharge(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:79
Definition: object.h:114
#define MSG_TYPE_VICTIM
Definition: newclient.h:392
Definition: object.h:181
object * object_new(void)
Definition: object.c:1037
const char * name_pl
Definition: object.h:315
object * create_archetype(const char *name)
Definition: arch.c:617
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.c:95
#define FOR_OB_AND_ABOVE_FINISH()
Definition: define.h:778
#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:2690
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:346
int32_t weight
Definition: object.h:365
#define MOVE_FLY_LOW
Definition: define.h:408
object * find_target_for_friendly_spell(object *op, int dir)
Definition: spell_util.c:856
void update_all_los(const mapstruct *map, int x, int y)
Definition: los.c:532
const char *const statname[NUM_STATS]
Definition: living.c:183
uint32_t tmp_invis
Definition: player.h:125
uint32_t flags[4]
Definition: object.h:415
struct mapdef * map
Definition: object.h:297
void monster_check_apply_all(object *monster)
Definition: monster.c:1821
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:535
object * transport
Definition: player.h:195
#define FLAG_IDENTIFIED
Definition: define.h:261
#define FOR_INV_FINISH()
Definition: define.h:712
#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:353
int16_t dam
Definition: living.h:45
#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:961
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:349
int is_true_undead(object *op)
Definition: player.c:3965
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:66
#define INS_NO_WALK_ON
Definition: object.h:570
int16_t last_grace
Definition: object.h:359
#define SMALL_NUGGET
int8_t direction
Definition: object.h:334
uint32_t nrof
Definition: object.h:333
int8_t Cha
Definition: living.h:35
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:1256
#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:248
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:1110
#define EXIT_Y(xyz)
Definition: define.h:458
#define MAX_BUF
Definition: define.h:35
char * ob_describe(const object *op, const object *observer, char *buf, size_t size)
Definition: ob_methods.c:85
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:733
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:36
#define tolower(C)
Definition: c_new.c:29
uint16_t difficulty
Definition: map.h:343
#define FOR_MAP_FINISH()
Definition: define.h:765
int8_t Str
Definition: living.h:35
int16_t resist[NROFATTACKS]
Definition: object.h:341
#define FLAG_KNOWN_CURSED
Definition: define.h:321
int need_identify(const object *op)
Definition: item.c:1332
#define FLAG_CURSED
Definition: define.h:317
unsigned int uint32_t
Definition: win32.h:162
Definition: object.h:107
int perceive_self(object *op)
Definition: spell_effect.c:995
object * check_inv_recursive(object *op, const object *trig)
Definition: button.c:786
void store_spell_expiry(object *spell)
Definition: spell_util.c:2028
object * object_find_by_type_subtype(const object *who, int type, int subtype)
Definition: object.c:4198
#define AT_POISON
Definition: attack.h:86
#define FLAG_ANIMATE
Definition: define.h:242
#define PREFER_HIGH
Definition: define.h:599
uint32_t attacktype
Definition: object.h:342
#define FLAG_GENERATOR
Definition: define.h:248
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.c:2463
uint8_t map_layer
Definition: object.h:422
StringBuffer * describe_item(const object *op, const object *owner, int use_media_tags, StringBuffer *buf)
Definition: item.c:981
#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:43
#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:430
int SP_level_range_adjust(const object *caster, const object *spob)
Definition: spell_util.c:379
#define MAP_PLAYER_UNIQUE
Definition: map.h:97
const char * localdir
Definition: global.h:243
tag_t count
Definition: object.h:299
living stats
Definition: object.h:368
#define FLAG_WIZCAST
Definition: define.h:290
int8_t Dex
Definition: living.h:35
struct archt * arch
Definition: object.h:412
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:338
struct Settings settings
Definition: init.c:40
void object_set_enemy(object *op, object *enemy)
Definition: object.c:679
void object_free2(object *ob, int flags)
Definition: object.c:1391
struct archt * next
Definition: object.h:467
uint32_t weapontype
Definition: object.h:371
#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:548
#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:785
#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:1438
#define ARCH_PORTAL_FAILED
Definition: object.h:581
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
#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:364
#define FLAG_MONSTER
Definition: define.h:245
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.c:838
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.c:302
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:740
int did_make_save(const object *op, int level, int bonus)
Definition: living.c:2199
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:758
MoveType move_block
Definition: object.h:425
int cast_create_missile(object *op, object *caster, object *spell, int dir, const char *stringarg)
Definition: spell_effect.c:498
void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action)
Definition: sounds.c:101
#define P_BLOCKSVIEW
Definition: map.h:226
void object_set_msg(object *op, const char *msg)
Definition: object.c:4698
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:3415
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:739
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.c:518
object * map_find_by_archetype(mapstruct *m, int x, int y, const archetype *at)
Definition: object.c:2944
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:4171
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
Definition: attack.c:1869
int16_t level
Definition: object.h:351
int8_t facing
Definition: object.h:335
void fix_object(object *op)
Definition: living.c:1118
EXTERN archetype * first_archetype
Definition: global.h:122
struct obj * more
Definition: object.h:295
object * arch_to_object(archetype *at)
Definition: arch.c:569
void object_update_speed(object *op)
Definition: object.c:1129
int32_t value
Definition: object.h:350
object * object_get_owner(object *op)
Definition: object.c:559
int8_t magic
Definition: object.h:348
static void polymorph_living(object *op, int level)
Definition: spell_effect.c:157
const char * name
Definition: object.h:466
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:746
#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:3039
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:705
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Definition: spell_util.c:1471
void object_remove(object *op)
Definition: object.c:1654
struct artifactstruct * next
Definition: artifact.h:18
int atnr_is_dragon_enabled(int attacknr)
Definition: player.c:95
int32_t food
Definition: living.h:47
static bool CAN_PROBE(const object *ob)
Definition: object.h:603
uint32_t count
Definition: player.h:109
Definition: object.h:224