Crossfire Server, Trunk  R21246
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_free(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_free(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_free(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  if (at == NULL) {
999  return 1;
1000  }
1001  object *tmp;
1002  const object *god;
1003  int i;
1004  StringBuffer *immunity;
1005 
1006  god = find_god(determine_god(op));
1007  if (god)
1009  "You worship %s",
1010  god->name);
1011  else
1013  "You worship no god");
1014 
1015  tmp = arch_present_in_ob(at, op);
1016 
1017  cp = stringbuffer_finish(describe_item(op, op, 0, NULL));
1018 
1019  if (*cp == '\0' && tmp == NULL)
1021  "You feel very mundane");
1022  else {
1024  "You have:");
1026  cp);
1027  if (tmp != NULL) {
1028  for (i = 0; i < NUM_STATS; i++) {
1029  if (get_attr_value(&tmp->stats, i) < 0) {
1031  "Your %s is depleted by %d",
1032  statname[i], -(get_attr_value(&tmp->stats, i)));
1033  }
1034  }
1035  }
1036  }
1037  free(cp);
1038 
1039  if (op->glow_radius > 0)
1041  "You glow in the dark.");
1042 
1043  immunity = NULL;
1044  for (tmp = op->inv; tmp; tmp = tmp->below) {
1045  if (tmp->type == SIGN) {
1046  if (immunity == NULL) {
1047  immunity = stringbuffer_new();
1048  stringbuffer_append_string(immunity, "You have been exposed to: ");
1049  } else {
1050  stringbuffer_append_string(immunity, ", ");
1051  }
1052  stringbuffer_append_string(immunity, tmp->name);
1053  if (tmp->level > 100)
1054  stringbuffer_append_string(immunity, " (full immunity)");
1055  else if (tmp->level > 70)
1056  stringbuffer_append_string(immunity, " (high immunity)");
1057  else if (tmp->level > 20)
1058  stringbuffer_append_string(immunity, " (partial immunity)");
1059  }
1060  }
1061 
1062  if (immunity != NULL) {
1063  cp = stringbuffer_finish(immunity);
1065  free(cp);
1066  }
1067 
1068  if (is_dragon_pl(op)) {
1069  /* now grab the 'dragon_ability'-force from the player's inventory */
1070  tmp = object_find_by_type_and_arch_name(op, FORCE, "dragon_ability_force");
1071  if (tmp != NULL) {
1072  StringBuffer *levels = NULL;
1073  int i;
1074 
1075  if (tmp->stats.exp == 0) {
1076  snprintf(buf, sizeof(buf), "Your metabolism isn't focused on anything.");
1077  } else {
1078  snprintf(buf, sizeof(buf), "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]);
1079  }
1081  buf);
1082 
1083  for (i = 0; i < NROFATTACKS; i++) {
1084  if (atnr_is_dragon_enabled(i) && tmp->resist[i] > 0) {
1085  if (levels == NULL) {
1086  levels = stringbuffer_new();
1087  stringbuffer_append_string(levels, "Ability levels:\n");
1088  }
1089  stringbuffer_append_printf(levels, "- %s: %d\n", change_resist_msg[i], tmp->resist[i]);
1090  }
1091  }
1092 
1093  if (levels != NULL) {
1094  cp = stringbuffer_finish(levels);
1096  free(cp);
1097  }
1098  }
1099  }
1100  return 1;
1101 }
1102 
1132 int cast_create_town_portal(object *op, object *caster, object *spell, int dir) {
1133  object *dummy, *force, *old_force, *tmp;
1134  archetype *perm_portal;
1135  char portal_name [1024], portal_message [1024];
1136  int16_t exitx, exity;
1137  mapstruct *exitmap;
1138  int op_level, x, y;
1139 
1140  /* Check to see if the map the player is currently on is a per player unique
1141  * map. This can be determined in that per player unique maps have the
1142  * full pathname listed. Ignore if settings.create_home_portals is true.
1143  */
1145  if (!strncmp(op->map->path, settings.localdir, strlen(settings.localdir))) {
1147  "You can't cast that here.");
1148  return 0;
1149  }
1150  }
1151 
1152  /* Check to see if the player is on a transport */
1153  if (op->contr && op->contr->transport) {
1155  "You need to exit the transport to cast that.");
1156  return 0;
1157  }
1158 
1159  /* The first thing to do is to check if we have a marked destination
1160  * dummy is used to make a check inventory for the force
1161  */
1162  dummy = arch_to_object(spell->other_arch);
1163  if (dummy == NULL) {
1165  "Oops, program error!");
1166  LOG(llevError, "object_new failed (force in cast_create_town_portal for %s!\n", op->name);
1167  return 0;
1168  }
1169  force = check_inv_recursive(op, dummy);
1170 
1171  if (force == NULL) {
1172  /* Here we know there is no destination marked up.
1173  * We have 2 things to do:
1174  * 1. Mark the destination in the player inventory.
1175  * 2. Let the player know it worked.
1176  */
1177  free_string(dummy->name);
1178  dummy->name = add_string(op->map->path);
1179  EXIT_X(dummy) = op->x;
1180  EXIT_Y(dummy) = op->y;
1181  dummy->weapontype = op->map->last_reset_time;
1182  object_insert_in_ob(dummy, op);
1184  "You fix this place in your mind and feel that you "
1185  "can come here from anywhere.");
1186  return 1;
1187  }
1189 
1190  /* Here we know where the town portal should go to
1191  * We should kill any existing portal associated with the player.
1192  * Than we should create the 2 portals.
1193  * For each of them, we need:
1194  * - To create the portal with the name of the player+destination map
1195  * - set the owner of the town portal
1196  * - To mark the position of the portal in the player's inventory
1197  * for easier destruction.
1198  *
1199  * The mark works has follow:
1200  * slaying: Existing town portal
1201  * hp, sp : x & y of the associated portal
1202  * name : name of the portal
1203  * race : map the portal is in
1204  */
1205 
1206  /* First step: killing existing town portals */
1207  dummy = create_archetype(spell->race);
1208  if (dummy == NULL) {
1210  "Oops, program error!");
1211  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1212  return 0;
1213  }
1214  perm_portal = find_archetype(spell->slaying);
1215  if (perm_portal == NULL) {
1217  "Oops, program error!");
1218  return 0;
1219  }
1220 
1221  /* To kill a town portal, we go trough the player's inventory,
1222  * for each marked portal in player's inventory,
1223  * -We try load the associated map (if impossible, consider the portal destructed)
1224  * -We find any portal in the specified location.
1225  * If it has the good name, we destruct it.
1226  * -We destruct the force indicating that portal.
1227  */
1228  while ((old_force = check_inv_recursive(op, dummy))) {
1229  exitx = EXIT_X(old_force);
1230  exity = EXIT_Y(old_force);
1231  LOG(llevDebug, "Trying to kill a portal in %s (%d,%d)\n", old_force->race, exitx, exity);
1232 
1233  if (!strncmp(old_force->race, settings.localdir, strlen(settings.localdir)))
1234  exitmap = ready_map_name(old_force->race, MAP_PLAYER_UNIQUE);
1235  else
1236  exitmap = ready_map_name(old_force->race, 0);
1237 
1238  if (exitmap) {
1239  tmp = map_find_by_archetype(exitmap, exitx, exity, perm_portal);
1241  if (tmp->name == old_force->name) {
1242  object_remove(tmp);
1243  object_free(tmp, 0);
1244  break;
1245  }
1247 
1248  /* kill any opening animation there is */
1249  archetype *arch = find_archetype("town_portal_open");
1250  if (arch != NULL) {
1251  tmp = map_find_by_archetype(exitmap, exitx, exity, arch);
1253  if (tmp->name == old_force->name) {
1254  object_remove(tmp);
1256  break;
1257  }
1259  }
1260  }
1261  object_remove(old_force);
1262  object_free(old_force, 0);
1263  LOG(llevDebug, "\n");
1264  }
1266 
1267  /* Creating the portals.
1268  * The very first thing to do is to ensure
1269  * access to the destination map.
1270  * If we can't, don't fizzle. Simply warn player.
1271  * This ensure player pays his mana for the spell
1272  * because HE is responsible for forgetting.
1273  * 'force' is the destination of the town portal, which we got
1274  * from the players inventory above.
1275  */
1276 
1277  /* Ensure exit map is loaded*/
1278  if (!strncmp(force->name, settings.localdir, strlen(settings.localdir)))
1279  exitmap = ready_map_name(force->name, MAP_PLAYER_UNIQUE);
1280  else
1281  exitmap = ready_map_name(force->name, 0);
1282 
1283  /* If we were unable to load (ex. random map deleted), warn player*/
1284  if (exitmap == NULL) {
1286  "Something strange happens. You can't remember where to go!?");
1287  object_remove(force);
1288  object_free(force, 0);
1290  return 1;
1291  } else if (exitmap->last_reset_time != force->weapontype) {
1293  "The spell effect has expired.");
1294  object_remove(force);
1295  object_free(force, 0);
1297  return 1;
1298  }
1299 
1300  op_level = caster_level(caster, spell);
1301  if (op_level < 15)
1302  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);
1303  else if (op_level < 30)
1304  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);
1305  else if (op_level < 60)
1306  snprintf(portal_message, 1024, "\nA shining door opens in the air in front of you, showing you the path to another place.\n");
1307  else
1308  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);
1309 
1310  /* Create a portal in front of player
1311  * dummy contain the portal and
1312  * force contain the track to kill it later
1313  */
1314 
1315  snprintf(portal_name, 1024, "%s's portal to %s", op->name, force->name);
1316  dummy = create_archetype(spell->slaying); /*The portal*/
1317  if (dummy == NULL) {
1319  "Oops, program error!");
1320  LOG(llevError, "object_new failed (perm_magic_portal) in cast_create_town_portal for %s!\n", op->name);
1321  return 0;
1322  }
1323  EXIT_PATH(dummy) = add_string(force->name);
1324  EXIT_X(dummy) = EXIT_X(force);
1325  EXIT_Y(dummy) = EXIT_Y(force);
1326  FREE_AND_COPY(dummy->name, portal_name);
1327  FREE_AND_COPY(dummy->name_pl, portal_name);
1328  object_set_msg(dummy, portal_message);
1329  dummy->race = add_string(op->name); /*Save the owner of the portal*/
1330 
1331  /* create a nice animation */
1332  tmp = create_archetype("town_portal_open");
1333  FREE_AND_COPY(tmp->name, portal_name);
1334  FREE_AND_COPY(tmp->name_pl, portal_name);
1335  object_insert_in_ob(dummy, tmp);
1336  /* and put it on the floor, when it ends the portal will be on the ground */
1337  cast_create_obj(op, tmp, 0);
1338  x = tmp->x;
1339  y = tmp->y;
1340 
1341  /* Now we need to to create a town portal marker inside the player
1342  * object, so on future castings, we can know that he has an active
1343  * town portal.
1344  */
1345  tmp = create_archetype(spell->race);
1346  if (tmp == NULL) {
1348  "Oops, program error!");
1349  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1350  return 0;
1351  }
1352  tmp->race = add_string(op->map->path);
1353  FREE_AND_COPY(tmp->name, portal_name);
1354  EXIT_X(tmp) = x;
1355  EXIT_Y(tmp) = y;
1356  object_insert_in_ob(tmp, op);
1357 
1358  /* Create a portal in the destination map
1359  * dummy contain the portal and
1360  * force the track to kill it later
1361  * the 'force' variable still contains the 'reminder' of
1362  * where this portal goes to.
1363  */
1364  snprintf(portal_name, 1024, "%s's portal to %s", op->name, op->map->path);
1365  dummy = create_archetype(spell->slaying); /*The portal*/
1366  if (dummy == NULL) {
1368  "Oops, program error!");
1369  LOG(llevError, "object_new failed (perm_magic_portal) in cast_create_town_portal for %s!\n", op->name);
1370  return 0;
1371  }
1372  EXIT_PATH(dummy) = add_string(op->map->path);
1373  EXIT_X(dummy) = op->x;
1374  EXIT_Y(dummy) = op->y;
1375  FREE_AND_COPY(dummy->name, portal_name);
1376  FREE_AND_COPY(dummy->name_pl, portal_name);
1377  object_set_msg(dummy, portal_message);
1378  dummy->race = add_string(op->name); /*Save the owner of the portal*/
1379 
1380  /* animation here too */
1381  tmp = create_archetype("town_portal_open");
1382  FREE_AND_COPY(tmp->name, portal_name);
1383  FREE_AND_COPY(tmp->name_pl, portal_name);
1384  object_insert_in_ob(dummy, tmp);
1385  /* and put it on the floor, when it ends the portal will be on the ground */
1386  object_insert_in_map_at(tmp, exitmap, op, 0, EXIT_X(force), EXIT_Y(force));
1387  x = tmp->x;
1388  y = tmp->y;
1389 
1390  /* Now we create another town portal marker that
1391  * points back to the one we just made
1392  */
1393  tmp = create_archetype(spell->race);
1394  if (tmp == NULL) {
1396  "Oops, program error!");
1397  LOG(llevError, "object_new failed (force) in cast_create_town_portal for %s!\n", op->name);
1398  return 0;
1399  }
1400  tmp->race = add_string(force->name);
1401  FREE_AND_COPY(tmp->name, portal_name);
1402  EXIT_X(tmp) = x;
1403  EXIT_Y(tmp) = y;
1404  object_insert_in_ob(tmp, op);
1405 
1406  /* Describe the player what happened
1407  */
1409  "You see air moving and showing you the way home.");
1410  object_remove(force); /* Delete the force inside the player*/
1411  object_free(force, 0);
1412  return 1;
1413 }
1414 
1415 
1433 int magic_wall(object *op, object *caster, int dir, object *spell_ob) {
1434  object *tmp, *tmp2;
1435  int i, posblocked, negblocked, maxrange;
1436  int16_t x, y;
1437  mapstruct *m;
1438  const char *name;
1439  archetype *at;
1440 
1441  if (!dir) {
1442  dir = op->facing;
1443  x = op->x;
1444  y = op->y;
1445  } else {
1446  x = op->x+freearr_x[dir];
1447  y = op->y+freearr_y[dir];
1448  }
1449  m = op->map;
1450 
1451  if ((spell_ob->move_block || x != op->x || y != op->y)
1452  && (get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE)
1453  || ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) == spell_ob->move_block))) {
1455  "Something is in the way.");
1456  return 0;
1457  }
1458  if (spell_ob->other_arch) {
1459  tmp = arch_to_object(spell_ob->other_arch);
1460  } else if (spell_ob->race) {
1461  char buf1[MAX_BUF];
1462 
1463  snprintf(buf1, sizeof(buf1), spell_ob->race, dir);
1464  at = find_archetype(buf1);
1465  if (!at) {
1466  LOG(llevError, "summon_wall: Unable to find archetype %s\n", buf1);
1468  "This spell is broken.");
1469  return 0;
1470  }
1471  tmp = arch_to_object(at);
1472  } else {
1473  LOG(llevError, "magic_wall: spell %s lacks other_arch\n", spell_ob->name);
1474  return 0;
1475  }
1476 
1477  if (tmp->type == SPELL_EFFECT) {
1478  tmp->attacktype = spell_ob->attacktype;
1479  tmp->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1480  tmp->stats.dam = spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob);
1481  tmp->range = 0;
1482  } else if (QUERY_FLAG(tmp, FLAG_ALIVE)) {
1483  tmp->stats.hp = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1484  tmp->stats.maxhp = tmp->stats.hp;
1485  object_set_owner(tmp, op);
1486  set_spell_skill(op, caster, spell_ob, tmp);
1487  }
1488  if (QUERY_FLAG(spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG(tmp, FLAG_IS_USED_UP)) {
1489  tmp->stats.food = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
1490  SET_FLAG(tmp, FLAG_IS_USED_UP);
1491  }
1492  if (QUERY_FLAG(spell_ob, FLAG_TEAR_DOWN)) {
1493  tmp->stats.hp = spell_ob->stats.dam+SP_level_dam_adjust(caster, spell_ob);
1494  tmp->stats.maxhp = tmp->stats.hp;
1495  SET_FLAG(tmp, FLAG_TEAR_DOWN);
1496  SET_FLAG(tmp, FLAG_ALIVE);
1497  }
1498 
1499  /* This can't really hurt - if the object doesn't kill anything,
1500  * these fields just won't be used.
1501  */
1502  object_set_owner(tmp, op);
1503  set_spell_skill(op, caster, spell_ob, tmp);
1504  tmp->level = caster_level(caster, spell_ob)/2;
1505 
1506  name = tmp->name;
1507  if ((tmp = object_insert_in_map_at(tmp, m, op, 0, x, y)) == NULL) {
1509  "Something destroys your %s",
1510  name);
1511  return 0;
1512  }
1513  /* If this is a spellcasting wall, need to insert the spell object */
1514  if (tmp->other_arch && tmp->other_arch->clone.type == SPELL)
1516 
1517  /* This code causes the wall to extend some distance in
1518  * each direction, or until an obstruction is encountered.
1519  * posblocked and negblocked help determine how far the
1520  * created wall can extend, it won't go extend through
1521  * blocked spaces.
1522  */
1523  maxrange = spell_ob->range+SP_level_range_adjust(caster, spell_ob);
1524  posblocked = 0;
1525  negblocked = 0;
1526 
1527  for (i = 1; i <= maxrange; i++) {
1528  int dir2;
1529 
1530  dir2 = (dir < 4) ? (dir+2) : dir-2;
1531 
1532  x = tmp->x+i*freearr_x[dir2];
1533  y = tmp->y+i*freearr_y[dir2];
1534  m = tmp->map;
1535 
1536  if (!(get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE))
1537  && ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block)
1538  && !posblocked) {
1539  tmp2 = object_new();
1540  object_copy(tmp, tmp2);
1541  object_insert_in_map_at(tmp2, m, op, 0, x, y);
1542  /* If this is a spellcasting wall, need to insert the spell object */
1543  if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
1545  } else
1546  posblocked = 1;
1547 
1548  x = tmp->x-i*freearr_x[dir2];
1549  y = tmp->y-i*freearr_y[dir2];
1550  m = tmp->map;
1551 
1552  if (!(get_map_flags(m, &m, x, y, &x, &y)&(P_OUT_OF_MAP|P_IS_ALIVE))
1553  && ((spell_ob->move_block&GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block)
1554  && !negblocked) {
1555  tmp2 = object_new();
1556  object_copy(tmp, tmp2);
1557  object_insert_in_map_at(tmp2, m, op, 0, x, y);
1558  if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
1560  } else
1561  negblocked = 1;
1562  }
1563 
1564  if (QUERY_FLAG(tmp, FLAG_BLOCKSVIEW))
1565  update_all_los(op->map, op->x, op->y);
1566 
1567  return 1;
1568 }
1569 
1586 int dimension_door(object *op, object *caster, object *spob, int dir) {
1587  uint32_t dist, maxdist;
1588  int mflags;
1589  mapstruct *m;
1590  int16_t sx, sy;
1591 
1592  if (op->type != PLAYER)
1593  return 0;
1594 
1595  if (!dir) {
1597  "In what direction?");
1598  return 0;
1599  }
1600 
1601  /* Given the new outdoor maps, can't let players dimension door for
1602  * ever, so put limits in.
1603  */
1604  maxdist = spob->range+SP_level_range_adjust(caster, spob);
1605 
1606  if (op->contr->count) {
1607  if (op->contr->count > maxdist) {
1609  "You can't dimension door that far!");
1610  return 0;
1611  }
1612 
1613  for (dist = 0; dist < op->contr->count; dist++) {
1614  mflags = get_map_flags(op->map, &m,
1615  op->x+freearr_x[dir]*(dist+1),
1616  op->y+freearr_y[dir]*(dist+1),
1617  &sx, &sy);
1618 
1619  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
1620  break;
1621 
1622  if ((mflags&P_BLOCKSVIEW)
1623  && OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1624  break;
1625  }
1626 
1627  if (dist < op->contr->count) {
1629  "Something blocks the magic of the spell.");
1630  op->contr->count = 0;
1631  return 0;
1632  }
1633  op->contr->count = 0;
1634 
1635  /* Remove code that puts player on random space on maps. IMO,
1636  * a lot of maps probably have areas the player should not get to,
1637  * but may not be marked as NO_MAGIC (as they may be bounded
1638  * by such squares). Also, there are probably treasure rooms and
1639  * lots of other maps that protect areas with no magic, but the
1640  * areas themselves don't contain no magic spaces.
1641  */
1642  /* This call here is really just to normalize the coordinates */
1643  mflags = get_map_flags(op->map, &m, op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist,
1644  &sx, &sy);
1645  if (mflags&P_IS_ALIVE || OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) {
1647  "You cast your spell, but nothing happens.");
1648  return 1; /* Maybe the penalty should be more severe... */
1649  }
1650  } else {
1651  /* Player didn't specify a distance, so lets see how far
1652  * we can move the player. Don't know why this stopped on
1653  * spaces that blocked the players view.
1654  */
1655 
1656  for (dist = 0; dist < maxdist; dist++) {
1657  mflags = get_map_flags(op->map, &m,
1658  op->x+freearr_x[dir]*(dist+1),
1659  op->y+freearr_y[dir]*(dist+1),
1660  &sx, &sy);
1661 
1662  if (mflags&(P_NO_MAGIC|P_OUT_OF_MAP))
1663  break;
1664 
1665  if ((mflags&P_BLOCKSVIEW)
1666  && OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1667  break;
1668  }
1669 
1670  /* If the destination is blocked, keep backing up until we
1671  * find a place for the player.
1672  */
1673  for (; dist > 0; dist--) {
1674  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))
1675  continue;
1676 
1677  if (!OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))
1678  break;
1679  }
1680  if (!dist) {
1682  "Your spell failed!");
1683  return 0;
1684  }
1685  }
1686 
1687  if (op->contr->transport && op->contr->transport->type == TRANSPORT) {
1688  ob_apply(op->contr->transport, op, 0);
1689  if (op->contr->transport) {
1691  "Your spell failed!");
1692  return 0;
1693  }
1694  }
1695 
1696  /* Actually move the player now */
1697  object_remove(op);
1698  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)
1699  return 1;
1700 
1701  if (op->type == PLAYER) {
1702  map_newmap_cmd(&op->contr->socket);
1704  }
1705  op->speed_left = -FABS(op->speed)*5; /* Freeze them for a short while */
1706  return 1;
1707 }
1708 
1709 
1722 int cast_heal(object *op, object *caster, object *spell, int dir) {
1723  object *target;
1724  archetype *at;
1725  object *poison;
1726  int heal = 0, success = 0;
1727 
1728  target = find_target_for_friendly_spell(op, dir);
1729 
1730  if (target == NULL)
1731  return 0;
1732 
1733  /* Figure out how many hp this spell might cure.
1734  * could be zero if this spell heals effects, not damage.
1735  */
1736  heal = spell->stats.dam;
1737  if (spell->stats.hp)
1738  heal += random_roll(spell->stats.hp, 6, op, PREFER_HIGH)+spell->stats.hp;
1739 
1740  if (heal) {
1741  if (target->stats.hp >= target->stats.maxhp) {
1743  "You are already fully healed.");
1744  } else {
1745  /* See how many points we actually heal. Instead of messages
1746  * based on type of spell, we instead do messages based
1747  * on amount of damage healed.
1748  */
1749  if (heal > (target->stats.maxhp-target->stats.hp))
1750  heal = target->stats.maxhp-target->stats.hp;
1751  target->stats.hp += heal;
1752 
1753  if (target->stats.hp >= target->stats.maxhp) {
1755  "You feel just fine!");
1756  } else if (heal > 50) {
1758  "Your wounds close!");
1759  } else if (heal > 25) {
1761  "Your wounds mostly close.");
1762  } else if (heal > 10) {
1764  "Your wounds start to fade.");
1765  } else {
1767  "Your wounds start to close.");
1768  }
1769  success = 1;
1770  }
1771  }
1772  if (spell->attacktype&AT_DISEASE)
1773  if (cure_disease(target, op, caster && caster->type != PLAYER ? caster->skill : spell->skill))
1774  success = 1;
1775 
1776  if (spell->attacktype&AT_POISON) {
1777  at = find_archetype("poisoning");
1778  if (at != NULL) {
1779  poison = arch_present_in_ob(at, target);
1780  if (poison) {
1781  success = 1;
1783  "Your body feels cleansed");
1784  poison->stats.food = 1;
1785  }
1786  }
1787  }
1788  if (spell->attacktype&AT_CONFUSION) {
1789  poison = object_present_in_ob_by_name(FORCE, "confusion", target);
1790  if (poison) {
1791  success = 1;
1793  "Your mind feels clearer");
1794  poison->duration = 1;
1795  }
1796  }
1797  if (spell->attacktype&AT_BLIND) {
1798  at = find_archetype("blindness");
1799  if (at != NULL) {
1800  poison = arch_present_in_ob(at, target);
1801  if (poison) {
1802  success = 1;
1804  "Your vision begins to return.");
1805  poison->stats.food = 1;
1806  }
1807  }
1808  }
1809  if (spell->last_sp && target->stats.sp < target->stats.maxsp) {
1810  target->stats.sp += spell->last_sp;
1811  if (target->stats.sp > target->stats.maxsp)
1812  target->stats.sp = target->stats.maxsp;
1813  success = 1;
1815  "Magical energies surge through your body!");
1816  }
1817  if (spell->last_grace && target->stats.grace < target->stats.maxgrace) {
1818  target->stats.grace += spell->last_grace;
1819  if (target->stats.grace > target->stats.maxgrace)
1820  target->stats.grace = target->stats.maxgrace;
1821  success = 1;
1823  "You feel redeemed with you god!");
1824  }
1825  if (spell->stats.food && target->stats.food < MAX_FOOD) {
1826  target->stats.food += spell->stats.food;
1827  if (target->stats.food > MAX_FOOD)
1828  target->stats.food = MAX_FOOD;
1829  success = 1;
1830  /* We could do something a bit better like the messages for healing above */
1832  "You feel your belly fill with food");
1833  }
1834 
1835  if (spell->other_arch != NULL && target->map != NULL) {
1836  object_insert_in_map_at(arch_to_object(spell->other_arch), target->map, NULL, INS_ON_TOP, target->x, target->y);
1837  }
1838 
1839  return success;
1840 }
1841 
1842 
1848 static const char *const no_gain_msgs[NUM_STATS] = {
1849  "You grow no stronger.",
1850  "You grow no more agile.",
1851  "You don't feel any healthier.",
1852  "no wis",
1853  "You are no easier to look at.",
1854  "no int",
1855  "no pow"
1856 };
1857 
1877 int cast_change_ability(object *op, object *caster, object *spell_ob, int dir, int silent) {
1878  object *tmp;
1879  object *force = NULL;
1880  int i;
1881 
1882  /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
1883  if (dir != 0) {
1884  tmp = find_target_for_friendly_spell(op, dir);
1885  } else {
1886  tmp = op;
1887  }
1888 
1889  if (tmp == NULL)
1890  return 0;
1891 
1892  /* If we've already got a force of this type, don't add a new one. */
1893  FOR_INV_PREPARE(tmp, tmp2)
1894  if (tmp2->type == FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
1895  if (tmp2->name == spell_ob->name) {
1896  force = tmp2; /* the old effect will be "refreshed" */
1897  break;
1898  } else if (spell_ob->race && spell_ob->race == tmp2->name) {
1899  if (!silent)
1901  "You can not cast %s while %s is in effect",
1902  spell_ob->name, tmp2->name_pl);
1903  return 0;
1904  }
1905  }
1906  FOR_INV_FINISH();
1907  if (force == NULL) {
1908  force = create_archetype(FORCE_NAME);
1909  force->subtype = FORCE_CHANGE_ABILITY;
1910  free_string(force->name);
1911  if (spell_ob->race)
1912  force->name = add_refcount(spell_ob->race);
1913  else
1914  force->name = add_refcount(spell_ob->name);
1915  free_string(force->name_pl);
1916  force->name_pl = add_refcount(spell_ob->name);
1917  } else {
1918  int duration;
1919 
1920  duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
1921  if (duration > force->duration) {
1922  force->duration = duration;
1924  "You recast the spell while in effect.");
1925 
1926  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
1927  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
1928  }
1929 
1930  } else {
1932  "Recasting the spell had no effect.");
1933  }
1934  return 1;
1935  }
1936  force->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
1937  if (op->type == PLAYER)
1938  store_spell_expiry(force);
1939  force->speed = 1.0;
1940  force->speed_left = -1.0;
1941  SET_FLAG(force, FLAG_APPLIED);
1942 
1943  /* Now start processing the effects. First, protections */
1944  for (i = 0; i < NROFATTACKS; i++) {
1945  if (spell_ob->resist[i]) {
1946  force->resist[i] = spell_ob->resist[i]+SP_level_dam_adjust(caster, spell_ob);
1947  if (force->resist[i] > 100)
1948  force->resist[i] = 100;
1949  }
1950  }
1951  if (spell_ob->stats.hp)
1952  force->stats.hp = spell_ob->stats.hp+SP_level_dam_adjust(caster, spell_ob);
1953 
1954  if (tmp->type == PLAYER) {
1955  /* Stat adjustment spells */
1956  for (i = 0; i < NUM_STATS; i++) {
1957  int8_t stat = get_attr_value(&spell_ob->stats, i), k, sm;
1958 
1959  if (stat) {
1960  sm = 0;
1961  for (k = 0; k < stat; k++)
1962  sm += rndm(1, 3);
1963 
1964  if ((get_attr_value(&tmp->stats, i)+sm) > (15+5*stat)) {
1965  sm = (15+5*stat)-get_attr_value(&tmp->stats, i);
1966  if (sm < 0)
1967  sm = 0;
1968  }
1969  set_attr_value(&force->stats, i, sm);
1970  if (!sm)
1972  no_gain_msgs[i]);
1973  }
1974  }
1975  }
1976 
1977  force->move_type = spell_ob->move_type;
1978 
1979  if (QUERY_FLAG(spell_ob, FLAG_SEE_IN_DARK))
1980  SET_FLAG(force, FLAG_SEE_IN_DARK);
1981 
1982  if (QUERY_FLAG(spell_ob, FLAG_XRAYS))
1983  SET_FLAG(force, FLAG_XRAYS);
1984 
1985  /* Haste/bonus speed */
1986  if (spell_ob->stats.exp) {
1987  if (op->speed > 0.5)
1988  force->stats.exp = (float)spell_ob->stats.exp/(op->speed+0.5);
1989  else
1990  force->stats.exp = spell_ob->stats.exp;
1991  }
1992 
1993  force->stats.wc = spell_ob->stats.wc;
1994  force->stats.ac = spell_ob->stats.ac;
1995  force->attacktype = spell_ob->attacktype;
1996 
1997  SET_FLAG(tmp, FLAG_NO_FIX_PLAYER); /* we don't want object_insert_in_ob() to call fix_object. */
1998  object_insert_in_ob(force, tmp);
2000  change_abil(tmp, force); /* Display any relevant messages, and call fix_object to update the player */
2001 
2002  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
2003  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
2004  }
2005 
2006  return 1;
2007 }
2008 
2025 int cast_bless(object *op, object *caster, object *spell_ob, int dir) {
2026  int i;
2027  const object *god = find_god(determine_god(op));
2028  object *force = NULL, *tmp;
2029 
2030  /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
2031  if (dir != 0) {
2032  tmp = find_target_for_friendly_spell(op, dir);
2033  } else {
2034  tmp = op;
2035  }
2036 
2037  /* If we've already got a force of this type, don't add a new one. */
2038  FOR_INV_PREPARE(tmp, tmp2)
2039  if (tmp2->type == FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
2040  if (tmp2->name == spell_ob->name) {
2041  force = tmp2; /* the old effect will be "refreshed" */
2042  break;
2043  } else if (spell_ob->race && spell_ob->race == tmp2->name) {
2045  "You can not cast %s while %s is in effect",
2046  spell_ob->name, tmp2->name_pl);
2047  return 0;
2048  }
2049  }
2050  FOR_INV_FINISH();
2051  if (force == NULL) {
2052  force = create_archetype(FORCE_NAME);
2053  force->subtype = FORCE_CHANGE_ABILITY;
2054  free_string(force->name);
2055  if (spell_ob->race)
2056  force->name = add_refcount(spell_ob->race);
2057  else
2058  force->name = add_refcount(spell_ob->name);
2059  free_string(force->name_pl);
2060  force->name_pl = add_refcount(spell_ob->name);
2061  } else {
2062  int duration;
2063 
2064  duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
2065  if (duration > force->duration) {
2066  force->duration = duration;
2068  "You recast the spell while in effect.");
2069  } else {
2071  "Recasting the spell had no effect.");
2072  }
2073  return 0;
2074  }
2075  force->duration = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob)*50;
2076  force->speed = 1.0;
2077  force->speed_left = -1.0;
2078 
2079  if (!god) {
2081  "Your blessing seems empty.");
2082  } else {
2083  /* Only give out good benefits, and put a max on it */
2084  const int16_t resist_max = spell_ob->resist[ATNR_GODPOWER];
2085  for (i = 0; i < NROFATTACKS; i++) {
2086  if (god->resist[i] > 0) {
2087  force->resist[i] = MIN(god->resist[i], resist_max);
2088  }
2089  }
2090  // Also grant appropriate amount of godpower resistance.
2091  force->resist[ATNR_GODPOWER] = spell_ob->resist[ATNR_GODPOWER];
2092 
2093  force->path_attuned |= god->path_attuned;
2094  if (spell_ob->attacktype) {
2095  force->attacktype |= god->attacktype|AT_PHYSICAL;
2096  if (god->slaying)
2097  force->slaying = add_string(god->slaying);
2098  }
2099  if (tmp != op) {
2101  "You bless %s.",
2102  tmp->name);
2104  "%s blessed you.",
2105  op->name);
2106  } else {
2108  "You are blessed by %s!",
2109  god->name);
2110  }
2111  }
2112  force->stats.wc = spell_ob->stats.wc;
2113  force->stats.ac = spell_ob->stats.ac;
2114 
2115  store_spell_expiry(force);
2116  object_insert_in_ob(force, tmp);
2117  SET_FLAG(force, FLAG_APPLIED);
2118  change_abil(tmp, force); /* To display any messages, will call fix_object() */
2119 
2120  if (spell_ob->other_arch != NULL && tmp->map != NULL) {
2121  object_insert_in_map_at(arch_to_object(spell_ob->other_arch), tmp->map, NULL, INS_ON_TOP, tmp->x, tmp->y);
2122  }
2123  return 1;
2124 }
2125 
2126 
2127 
2128 /*
2129  * Alchemy code by Mark Wedel
2130  *
2131  * This code adds a new spell, called alchemy. Alchemy will turn
2132  * objects to gold nuggets, the value of the gold nuggets being
2133  * from 5% to 40% of that of the item itself depending on casting level.
2134  * It uses the value of the object before charisma adjustments, because
2135  * the nuggets themselves will be will be adjusted by charisma when sold.
2136  *
2137  * Large nuggets are worth 25 gp each (base). You will always get
2138  * the maximum number of large nuggets you could get.
2139  * Small nuggets are worth 1 gp each (base). You will get from 0
2140  * to the max amount of small nuggets as you could get.
2141  *
2142  * For example, if an item is worth 110 gold, you will get
2143  * 4 large nuggets, and from 0-10 small nuggets.
2144  *
2145  * There is also a chance (1:30) that you will get nothing at all
2146  * for the object. There is also a maximum weight that will be
2147  * alchemied.
2148  */
2149 
2150 #define SMALL_NUGGET "smallnugget"
2151 #define LARGE_NUGGET "largenugget"
2152 
2167 static void alchemy_object(float value_adj, object *obj, int *small_nuggets, int *large_nuggets, int *weight) {
2168  uint64_t value = price_base(obj);
2169  uint64_t small_value, large_value;
2171  /* Multiply the value of the object by value_adj, which should range
2172  * from 0.05 to 0.40. Set value to 0 instead if unpaid.
2173  */
2174  if (QUERY_FLAG(obj, FLAG_UNPAID))
2175  value = 0;
2176  else
2177  value *= value_adj;
2178 
2179  archetype *small_nugget_arch = find_archetype(SMALL_NUGGET);
2180  if (small_nugget_arch == NULL) {
2181  return;
2182  }
2183  small_value = price_base(&small_nugget_arch->clone);
2184  archetype *large_nugget_arch = find_archetype(LARGE_NUGGET);
2185  if (large_nugget_arch == NULL) {
2186  return;
2187  }
2188  large_value = price_base(&large_nugget_arch->clone);
2189 
2190  /* Give half of what value_adj says when we alchemy money (This should
2191  * hopefully make it so that it isn't worth it to alchemy money, sell
2192  * the nuggets, alchemy the gold from that, etc.
2193  */
2194  if (value && (obj->type == MONEY || obj->type == GEM))
2195  value /= 2;
2196 
2197  if ((obj->value > 0) && rndm(0, 29)) {
2198  int count;
2199 
2200  assert(large_value != 0 && small_value != 0);
2201  count = value/large_value;
2202  *large_nuggets += count;
2203  value -= (uint64_t)count*large_value;
2204  count = value/small_value;
2205  *small_nuggets += count;
2206  }
2207 
2208  /* Turn 25 small nuggets into 1 large nugget. If the value
2209  * of large nuggets is not evenly divisable by the small nugget
2210  * value, take off an extra small_nugget (Assuming small_nuggets!=0)
2211  */
2212  if (*small_nuggets*small_value >= large_value) {
2213  assert(small_value != 0);
2214  (*large_nuggets)++;
2215  *small_nuggets -= large_value/small_value;
2216  if (*small_nuggets && large_value%small_value)
2217  (*small_nuggets)--;
2218  }
2219 
2220  if (weight != NULL) {
2221  *weight += obj->weight;
2222  }
2223 
2224  object_remove(obj);
2226 }
2227 
2241 static void place_alchemy_objects(object *op, mapstruct *m, int small_nuggets, int large_nuggets, int x, int y) {
2242  object *tmp;
2243  int flag = 0;
2244 
2245  /* Put any nuggets below the player, but we can only pass this
2246  * flag if we are on the same space as the player
2247  */
2248  if (x == op->x && y == op->y && op->map == m)
2249  flag = INS_BELOW_ORIGINATOR;
2250 
2251  if (small_nuggets) {
2253  tmp-> nrof = small_nuggets;
2254  object_insert_in_map_at(tmp, m, op, flag, x, y);
2255  }
2256  if (large_nuggets) {
2258  tmp-> nrof = large_nuggets;
2259  object_insert_in_map_at(tmp, m, op, flag, x, y);
2260  }
2261 }
2262 
2277 int alchemy(object *op, object *caster, object *spell_ob) {
2278  int x, y, weight = 0, weight_max, large_nuggets, small_nuggets, mflags;
2279  int16_t nx, ny;
2280  float value_adj;
2281  mapstruct *mp;
2282 
2283  if (op->type != PLAYER)
2284  return 0;
2285 
2286  /* Put a maximum weight of items that can be alchemied. Limits the power
2287  * some, and also prevents people from alcheming every table/chair/clock
2288  * in sight
2289  */
2290  weight_max = spell_ob->duration+SP_level_duration_adjust(caster, spell_ob);
2291  weight_max *= 1000;
2292 
2293  /* Set value_adj to be a multiplier for how much of the original value
2294  * will be in the nuggets. Starts at 0.05, increasing by 0.01 per casting
2295  * level, maxing out at 0.40.
2296  */
2297  value_adj = (SP_level_dam_adjust(caster, spell_ob)/100.00)+0.05;
2298 
2299  if (value_adj > 0.40)
2300  value_adj = 0.40;
2301 
2302  for (y = op->y-1; y <= op->y+1; y++) {
2303  for (x = op->x-1; x <= op->x+1; x++) {
2304  nx = x;
2305  ny = y;
2306 
2307  mp = op->map;
2308 
2309  mflags = get_map_flags(mp, &mp, nx, ny, &nx, &ny);
2310 
2311  if (mflags&(P_OUT_OF_MAP|P_NO_MAGIC))
2312  continue;
2313 
2314  /* Treat alchemy a little differently - most spell effects
2315  * use fly as the movement type - for alchemy, consider it
2316  * ground level effect.
2317  */
2318  if (GET_MAP_MOVE_BLOCK(mp, nx, ny)&MOVE_WALK)
2319  continue;
2320 
2321  small_nuggets = 0;
2322  large_nuggets = 0;
2323 
2324  FOR_MAP_PREPARE(mp, nx, ny, tmp) {
2325  if (tmp->weight > 0 && !QUERY_FLAG(tmp, FLAG_NO_PICK)
2326  && !QUERY_FLAG(tmp, FLAG_ALIVE)
2327  && !QUERY_FLAG(tmp, FLAG_IS_CAULDRON)) {
2328  if (tmp->inv) {
2329  FOR_INV_PREPARE(tmp, tmp1)
2330  if (tmp1->weight > 0 && !QUERY_FLAG(tmp1, FLAG_NO_PICK)
2331  && !QUERY_FLAG(tmp1, FLAG_ALIVE)
2332  && !QUERY_FLAG(tmp1, FLAG_IS_CAULDRON))
2333  alchemy_object(value_adj, tmp1, &small_nuggets, &large_nuggets, &weight);
2334  FOR_INV_FINISH();
2335  }
2336  alchemy_object(value_adj, tmp, &small_nuggets, &large_nuggets, &weight);
2337 
2338  if (weight > weight_max) {
2339  place_alchemy_objects(op, mp, small_nuggets, large_nuggets, nx, ny);
2340  return 1;
2341  }
2342  } /* is alchemable object */
2343  } FOR_MAP_FINISH(); /* process all objects on this space */
2344 
2345  /* Insert all the nuggets at one time. This probably saves time, but
2346  * it also prevents us from alcheming nuggets that were just created
2347  * with this spell.
2348  */
2349  place_alchemy_objects(op, mp, small_nuggets, large_nuggets, nx, ny);
2350  }
2351  }
2352 
2353  /* reset this so that if player standing on a big pile of stuff,
2354  * it is redrawn properly.
2355  */
2356  op->contr->socket.look_position = 0;
2357  return 1;
2358 }
2359 
2360 
2375 int remove_curse(object *op, object *caster, object *spell) {
2376  int success = 0, was_one = 0;
2377 
2378  FOR_INV_PREPARE(op, tmp)
2379  if (QUERY_FLAG(tmp, FLAG_APPLIED)
2380  && ((QUERY_FLAG(tmp, FLAG_CURSED) && QUERY_FLAG(spell, FLAG_CURSED))
2381  || (QUERY_FLAG(tmp, FLAG_DAMNED) && QUERY_FLAG(spell, FLAG_DAMNED)))) {
2382  was_one++;
2383  if (tmp->level <= caster_level(caster, spell)) {
2384  success++;
2385  if (QUERY_FLAG(spell, FLAG_DAMNED))
2386  CLEAR_FLAG(tmp, FLAG_DAMNED);
2387 
2388  CLEAR_FLAG(tmp, FLAG_CURSED);
2390  tmp->value = 0; /* Still can't sell it */
2391  if (op->type == PLAYER)
2392  esrv_update_item(UPD_FLAGS, op, tmp);
2393  }
2394  }
2395  FOR_INV_FINISH();
2396 
2397  if (op->type == PLAYER) {
2398  if (success) {
2400  "You feel like some of your items are looser now.");
2401  } else {
2402  if (was_one)
2404  "You failed to remove the curse.");
2405  else
2407  "You are not using any cursed items.");
2408  }
2409  }
2410  return success;
2411 }
2412 
2425 int cast_item_curse_or_curse(object *op, object *caster, object *spell_ob) {
2426  object *marked = find_marked_object(op);
2427  char name[HUGE_BUF];
2428 
2429  if (!marked) {
2431  "You need to mark an item first!");
2432  return 0;
2433  }
2434 
2435  if ((QUERY_FLAG(marked, FLAG_CURSED) && QUERY_FLAG(spell_ob, FLAG_CURSED))
2436  || (QUERY_FLAG(marked, FLAG_BLESSED) && QUERY_FLAG(spell_ob, FLAG_BLESSED))) {
2438  "The spell has no effect");
2439  return 0;
2440  }
2441 
2442  query_short_name(marked, name, HUGE_BUF);
2443  if (QUERY_FLAG(spell_ob, FLAG_CURSED)) {
2445  "Your %s emits a dark light for a few seconds.", name);
2446  SET_FLAG(marked, FLAG_CURSED);
2447  CLEAR_FLAG(marked, FLAG_KNOWN_CURSED);
2448  CLEAR_FLAG(marked, FLAG_IDENTIFIED);
2449  esrv_update_item(UPD_FLAGS, op, marked);
2450  return 1;
2451  }
2452 
2454  "Your %s glows blue for a few seconds.", name);
2455  SET_FLAG(marked, FLAG_BLESSED);
2456  SET_FLAG(marked, FLAG_KNOWN_BLESSED);
2457  SET_FLAG(marked, FLAG_STARTEQUIP);
2458  esrv_update_item(UPD_FLAGS, op, marked);
2459  return 1;
2460 }
2461 
2476 int cast_identify(object *op, object *caster, object *spell) {
2477  int success = 0, num_ident;
2478  char desc[MAX_BUF];
2479 
2480  num_ident = spell->stats.dam+SP_level_dam_adjust(caster, spell);
2481 
2482  if (num_ident < 1)
2483  num_ident = 1;
2484 
2485  FOR_INV_PREPARE(op, tmp)
2486  if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify(tmp)) {
2487  tmp = identify(tmp);
2488  if (op->type == PLAYER) {
2490  "You have %s.",
2491  ob_describe(tmp, op, desc, sizeof(desc)));
2492  if (tmp->msg) {
2494  "The item has a story:\n%s",
2495  tmp->msg);
2496  }
2497  }
2498  num_ident--;
2499  success = 1;
2500  if (!num_ident)
2501  break;
2502  }
2503  FOR_INV_FINISH();
2504  /* If all the power of the spell has been used up, don't go and identify
2505  * stuff on the floor. Only identify stuff on the floor if the spell
2506  * was not fully used.
2507  */
2508  if (num_ident) {
2509  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp)
2510  if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED)
2511  && !tmp->invisible
2512  && need_identify(tmp)) {
2513  tmp = identify(tmp);
2514  if (op->type == PLAYER) {
2516  "On the ground is %s.",
2517  ob_describe(tmp, op, desc, sizeof(desc)));
2518  if (tmp->msg) {
2520  "The item has a story:\n%s",
2521  tmp->msg);
2522  }
2524  }
2525  num_ident--;
2526  success = 1;
2527  if (!num_ident)
2528  break;
2529  }
2530  FOR_MAP_FINISH();
2531  }
2532  if (!success)
2534  "You can't reach anything unidentified.");
2535  else {
2536  spell_effect(spell, op->x, op->y, op->map, op);
2537  }
2538  return success;
2539 }
2540 
2553 int cast_detection(object *op, object *caster, object *spell) {
2554  object *tmp, *last, *detect;
2555  const object *god;
2556  int done_one, range, mflags, floor, level;
2557  int16_t x, y, nx, ny;
2558  mapstruct *m;
2559 
2560  /* We precompute some values here so that we don't have to keep
2561  * doing it over and over again.
2562  */
2563  god = find_god(determine_god(op));
2564  level = caster_level(caster, spell);
2565  range = spell->range+SP_level_range_adjust(caster, spell);
2566 
2567  for (x = op->x-range; x <= op->x+range; x++)
2568  for (y = op->y-range; y <= op->y+range; y++) {
2569  m = op->map;
2570  mflags = get_map_flags(m, &m, x, y, &nx, &ny);
2571  if (mflags&P_OUT_OF_MAP)
2572  continue;
2573 
2574  /* For most of the detections, we only detect objects above the
2575  * floor. But this is not true for show invisible.
2576  * Basically, we just go and find the top object and work
2577  * down - that is easier than working up.
2578  */
2579 
2580  last = NULL;
2581  FOR_MAP_PREPARE(m, nx, ny, tmp)
2582  last = tmp;
2583  FOR_MAP_FINISH();
2584  /* Shouldn't happen, but if there are no objects on a space, this
2585  * would happen.
2586  */
2587  if (!last)
2588  continue;
2589 
2590  done_one = 0;
2591  floor = 0;
2592  detect = NULL;
2593  tmp = last;
2595  /* show invisible */
2596  if (QUERY_FLAG(spell, FLAG_MAKE_INVIS)
2597  /* Might there be other objects that we can make visibile? */
2598  && (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) ||
2599  (tmp->type == PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)) ||
2600  tmp->type == CF_HANDLE ||
2601  tmp->type == TRAPDOOR || tmp->type == EXIT || tmp->type == HOLE ||
2602  tmp->type == BUTTON || tmp->type == TELEPORTER ||
2603  tmp->type == GATE || tmp->type == LOCKED_DOOR ||
2604  tmp->type == WEAPON || tmp->type == ALTAR || tmp->type == SIGN ||
2605  tmp->type == TRIGGER_PEDESTAL || tmp->type == SPECIAL_KEY ||
2606  tmp->type == TREASURE || tmp->type == BOOK ||
2607  tmp->type == HOLY_ALTAR))) {
2608  if (random_roll(0, level-1, op, PREFER_HIGH) > tmp->level) {
2609  tmp->invisible = 0;
2610  done_one = 1;
2611  }
2612  }
2613  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
2614  floor = 1;
2615 
2616  /* All detections below this point don't descend beneath the floor,
2617  * so just continue on. We could be clever and look at the type of
2618  * detection to completely break out if we don't care about objects beneath
2619  * the floor, but once we get to the floor, not likely a very big issue anyways.
2620  */
2621  if (floor)
2622  continue;
2623 
2624  /* I had thought about making detect magic and detect curse
2625  * show the flash the magic item like it does for detect monster.
2626  * however, if the object is within sight, this would then make it
2627  * difficult to see what object is magical/cursed, so the
2628  * effect wouldn't be as apparent.
2629  */
2630 
2631  /* detect magic */
2632  if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)
2633  && !QUERY_FLAG(tmp, FLAG_KNOWN_MAGICAL)
2634  && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)
2635  && is_magical(tmp)) {
2637  /* make runes more visible */
2638  if (tmp->type == RUNE && tmp->attacktype&AT_MAGIC)
2639  tmp->stats.Cha /= 4;
2640  done_one = 1;
2641  }
2642  /* detect monster */
2643  if (QUERY_FLAG(spell, FLAG_MONSTER)
2644  && (QUERY_FLAG(tmp, FLAG_MONSTER) || (tmp->type == PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)))) {
2645  done_one = 2;
2646  if (!detect)
2647  detect = tmp;
2648  }
2649  /* Basically, if race is set in the spell, then the creatures race must
2650  * match that. if the spell race is set to GOD, then the gods opposing
2651  * race must match.
2652  */
2653  if (spell->race
2654  && QUERY_FLAG(tmp, FLAG_MONSTER)
2655  && tmp->race
2656  && ((!strcmp(spell->race, "GOD") && god && god->slaying && strstr(god->slaying, tmp->race)) || (strstr(spell->race, tmp->race)))) {
2657  done_one = 2;
2658  if (!detect)
2659  detect = tmp;
2660  }
2661  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED)
2662  && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED)
2663  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
2665  done_one = 1;
2666  }
2667  } FOR_OB_AND_BELOW_FINISH(); /* for stack of objects on this space */
2668 
2669  /* Code here puts an effect of the spell on the space, so you can see
2670  * where the magic is.
2671  */
2672  if (done_one) {
2673  object *detect_ob;
2674  int dx = nx, dy = ny;
2675 
2676  /* if this is set, we want to copy the face */
2677  if (done_one == 2 && detect) {
2678  /*
2679  * We can't simply copy the face to a single item, because
2680  * multipart objects need to have multipart glows.
2681  * So copy the initial item, erase some properties, and use that.
2682  */
2683 
2684  object *part;
2685  int flag;
2686 
2687  dx = HEAD(detect)->x;
2688  dy = HEAD(detect)->y;
2689 
2690  detect_ob = object_create_arch(HEAD(detect)->arch);
2691  for (part = detect_ob; part != NULL; part = part->more) {
2692  if (part->arch->reference_count > 0)
2693  part->arch->reference_count++;
2694  part->last_anim = 0;
2695  part->type = spell->other_arch->clone.type;
2696  for (flag = 0; flag < 4; flag++) {
2697  part->flags[flag] = spell->other_arch->clone.flags[flag];
2698  }
2699  part->stats.food = spell->other_arch->clone.stats.food;
2700  part->last_anim = 0;
2701  part->speed = spell->other_arch->clone.speed;
2702  part->speed_left = spell->other_arch->clone.speed_left;
2703  part->move_allow = spell->other_arch->clone.move_allow;
2704  part->move_block = spell->other_arch->clone.move_block;
2705  part->move_type = spell->other_arch->clone.move_type;
2706  part->glow_radius = spell->other_arch->clone.glow_radius;
2707  part->invisible = spell->other_arch->clone.invisible;
2708  part->weight = spell->other_arch->clone.weight;
2709  part->map_layer = spell->other_arch->clone.map_layer;
2710  FREE_AND_COPY(part->name, spell->other_arch->clone.name);
2711 
2712  /* by default, the detect_ob is already animated */
2713  if (!QUERY_FLAG(detect, FLAG_ANIMATE))
2714  CLEAR_FLAG(part, FLAG_ANIMATE);
2715  }
2716  object_update_speed(detect_ob);
2717  } else
2718  detect_ob = arch_to_object(spell->other_arch);
2719 
2720  object_insert_in_map_at(detect_ob, m, op, 0, dx, dy);
2721  }
2722  } /* for processing the surrounding spaces */
2723 
2724 
2725  /* Now process objects in the players inventory if detect curse or magic */
2726  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) || QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)) {
2727  done_one = 0;
2728  FOR_INV_PREPARE(op, tmp) {
2729  if (!tmp->invisible && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)) {
2730  if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)
2731  && is_magical(tmp)
2732  && !QUERY_FLAG(tmp, FLAG_KNOWN_MAGICAL)) {
2734  if (op->type == PLAYER)
2735  esrv_send_item(op, tmp);
2736  }
2737  if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED)
2738  && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED)
2739  && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
2741  if (op->type == PLAYER)
2742  esrv_send_item(op, tmp);
2743  }
2744  } /* if item is not identified */
2745  } FOR_INV_FINISH(); /* for the players inventory */
2746  } /* if detect magic/curse and object is a player */
2747  return 1;
2748 }
2749 
2757 static void charge_mana_effect(object *victim, int caster_level) {
2758  /* Prevent explosions for objects without mana. Without this check, doors
2759  * will explode, too.
2760  */
2761  if (victim->stats.maxsp <= 0)
2762  return;
2763 
2765  "You feel energy course through you.");
2766 
2767  if (victim->stats.sp >= victim->stats.maxsp*2) {
2768  object *tmp;
2769 
2771  "Your head explodes!");
2772 
2773  /* Explodes a fireball centered at player */
2775  tmp->dam_modifier = random_roll(1, caster_level, victim, PREFER_LOW)/5+1;
2776  tmp->stats.maxhp = random_roll(1, caster_level, victim, PREFER_LOW)/10+2;
2777  object_insert_in_map_at(tmp, victim->map, NULL, 0, victim->x, victim->y);
2778  victim->stats.sp = 2*victim->stats.maxsp;
2779  } else if (victim->stats.sp >= victim->stats.maxsp*1.88) {
2781  "You feel like your head is going to explode.");
2782  } else if (victim->stats.sp >= victim->stats.maxsp*1.66) {
2784  "You get a splitting headache!");
2785  } else if (victim->stats.sp >= victim->stats.maxsp*1.5) {
2787  "Chaos fills your world.");
2788  confuse_living(victim, victim, 99);
2789  } else if (victim->stats.sp >= victim->stats.maxsp*1.25) {
2791  "You start hearing voices.");
2792  }
2793 }
2794 
2812 int cast_transfer(object *op, object *caster, object *spell, int dir) {
2813  object *plyr = NULL;
2814  int16_t x, y;
2815  mapstruct *m;
2816  int mflags;
2817 
2818  m = op->map;
2819  x = op->x+freearr_x[dir];
2820  y = op->y+freearr_y[dir];
2821 
2822  mflags = get_map_flags(m, &m, x, y, &x, &y);
2823  if (!(mflags&P_OUT_OF_MAP) && mflags&P_IS_ALIVE) {
2824  FOR_MAP_PREPARE(m, x, y, tmp)
2825  plyr = tmp;
2826  if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
2827  break;
2828  FOR_MAP_FINISH();
2829  }
2830 
2831  /* If we did not find a player in the specified direction, transfer
2832  * to anyone on top of us. This is used for the rune of transference mostly.
2833  */
2834  if (plyr == NULL)
2835  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp)
2836  plyr = tmp;
2837  if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
2838  break;
2839  FOR_MAP_FINISH();
2840 
2841  if (!plyr) {
2843  "There is no one there.");
2844  return 0;
2845  }
2846 
2847  /* give sp */
2848  if (spell->stats.dam > 0) {
2849  plyr->stats.sp += spell->stats.dam+SP_level_dam_adjust(caster, spell);
2850  charge_mana_effect(plyr, caster_level(caster, spell));
2851  return 1;
2852  /* suck sp away. Can't suck sp from yourself */
2853  } else if (op != plyr) {
2854  /* old dragin magic used floats. easier to just use ints and divide by 100 */
2855 
2856  int rate = -spell->stats.dam+SP_level_dam_adjust(caster, spell), sucked;
2857 
2858  if (rate > 95)
2859  rate = 95;
2860 
2861  sucked = (plyr->stats.sp*rate)/100;
2862  plyr->stats.sp -= sucked;
2863  if (QUERY_FLAG(op, FLAG_ALIVE)) {
2864  /* Player doesn't get full credit */
2865  sucked = (sucked*rate)/100;
2866  op->stats.sp += sucked;
2867  if (sucked > 0) {
2868  charge_mana_effect(op, caster_level(caster, spell));
2869  }
2870  }
2871  return 1;
2872  }
2873  return 0;
2874 }
2875 
2885 void counterspell(object *op, int dir) {
2886  object *head;
2887  int mflags;
2888  mapstruct *m;
2889  int16_t sx, sy;
2890 
2891  sx = op->x+freearr_x[dir];
2892  sy = op->y+freearr_y[dir];
2893  m = op->map;
2894  mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
2895  if (mflags&P_OUT_OF_MAP)
2896  return;
2897 
2898  FOR_MAP_PREPARE(m, sx, sy, tmp) {
2899  object *owner;
2900 
2901  /* Need to look at the head object - otherwise, if tmp
2902  * points to a monster, we don't have all the necessary
2903  * info for it.
2904  */
2905  head = HEAD(tmp);
2906 
2907  /* don't attack our own spells */
2908  owner = object_get_owner(tmp);
2909  if (owner != NULL && owner == object_get_owner(op))
2910  continue;
2911 
2912  /* Basically, if the object is magical and not counterspell,
2913  * we will more or less remove the object. Don't counterspell
2914  * monsters either.
2915  */
2916 
2917  if (head->attacktype&AT_MAGIC
2918  && !(head->attacktype&AT_COUNTERSPELL)
2919  && !QUERY_FLAG(head, FLAG_MONSTER)
2920  && (op->level > head->level)) {
2921  object_remove(head);
2922  object_free(head, 0);
2923  } else switch (head->type) {
2924  case SPELL_EFFECT:
2925  if ((op->level > head->level) && !op->stats.food && !op->speed_left) {
2926  object_remove(head);
2927  object_free(head, 0);
2928  }
2929  break;
2930 
2931  /* I really don't get this rune code that much - that
2932  * random chance seems really low.
2933  */
2934  case RUNE:
2935  if (rndm(0, 149) == 0) {
2936  head->stats.hp--; /* weaken the rune */
2937  if (!head->stats.hp) {
2938  object_remove(head);
2939  object_free(head, 0);
2940  }
2941  }
2942  break;
2943  }
2944  } FOR_MAP_FINISH();
2945 }
2946 
2961 int cast_consecrate(object *op, object *caster, object *spell) {
2962  char buf[MAX_BUF];
2963  const object *god = find_god(determine_god(op));
2964 
2965  if (!god) {
2967  "You can't consecrate anything if you don't worship a god!");
2968  return 0;
2969  }
2970 
2971  FOR_BELOW_PREPARE(op, tmp) {
2972  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR))
2973  break;
2974  if (tmp->type == HOLY_ALTAR) {
2975  if (tmp->level > caster_level(caster, spell)) {
2977  "You are not powerful enough to reconsecrate the %s",
2978  tmp->name);
2979  return 0;
2980  } else {
2981  /* If we got here, we are consecrating an altar */
2982  object *new_altar;
2983  size_t letter;
2984  archetype *altar_arch;
2985 
2986  snprintf(buf, MAX_BUF, "altar_");
2987  letter = strlen(buf);
2988  strncpy(buf+letter, god->name, MAX_BUF-letter);
2989  for (; letter < strlen(buf); letter++)
2990  buf[letter] = tolower(buf[letter]);
2991  altar_arch = find_archetype(buf);
2992  if (!altar_arch) {
2994  "You fail to consecrate the altar.");
2995  LOG(llevError, "cast_consecrate: can't find altar %s for god %s\n", buf, god->name);
2996  return 0;
2997  }
2998  new_altar = arch_to_object(altar_arch);
2999  new_altar->level = tmp->level;
3000  if (QUERY_FLAG(tmp, FLAG_IS_BUILDABLE))
3001  SET_FLAG(new_altar, FLAG_IS_BUILDABLE);
3002  object_insert_in_map_at(new_altar, tmp->map, tmp, INS_BELOW_ORIGINATOR, tmp->x, tmp->y);
3003  object_remove(tmp);
3005  "You consecrated the altar to %s!",
3006  god->name);
3007  return 1;
3008  }
3009  }
3010  } FOR_BELOW_FINISH();
3012  "You are not standing over an altar!");
3013  return 0;
3014 }
3015 
3039 int animate_weapon(object *op, object *caster, object *spell, int dir) {
3040  object *weapon, *tmp;
3041  char buf[MAX_BUF];
3042  int a, i;
3043  int16_t x, y;
3044  mapstruct *m;
3045  materialtype_t *mt;
3046 
3047  if (!spell->other_arch) {
3049  "Oops, program error!");
3050  LOG(llevError, "animate_weapon failed: spell %s missing other_arch!\n", spell->name);
3051  return 0;
3052  }
3053 
3054  /* exit if it's not a player using this spell. */
3055  if (op->type != PLAYER)
3056  return 0;
3057 
3058  /* if player already has a golem, abort */
3059  if (op->contr->ranges[range_golem] != NULL && op->contr->golem_count == op->contr->ranges[range_golem]->count) {
3061  return 0;
3062  }
3063 
3064  /* if no direction specified, pick one */
3065  if (!dir) {
3066  dir = object_find_free_spot(NULL, op->map, op->x, op->y, 1, 9);
3067  assert(dir != -1);
3068  }
3069 
3070  m = op->map;
3071  x = op->x+freearr_x[dir];
3072  y = op->y+freearr_y[dir];
3073 
3074  /* if there's no place to put the golem, abort */
3075  if ((dir == -1)
3076  || (get_map_flags(m, &m, x, y, &x, &y)&P_OUT_OF_MAP)
3077  || ((spell->other_arch->clone.move_type&GET_MAP_MOVE_BLOCK(m, x, y)) == spell->other_arch->clone.move_type)) {
3079  "There is something in the way.");
3080  return 0;
3081  }
3082 
3083  /* Use the weapon marked by the player. */
3084  weapon = find_marked_object(op);
3085 
3086  if (!weapon) {
3088  "You must mark a weapon to use with this spell!");
3089  return 0;
3090  }
3091  if (spell->race && strcmp(weapon->arch->name, spell->race)) {
3093  "The spell fails to transform your weapon.");
3094  return 0;
3095  }
3096  if (weapon->type != WEAPON) {
3098  "You need to mark a weapon to animate it.");
3099  return 0;
3100  }
3101  if (QUERY_FLAG(weapon, FLAG_UNPAID)) {
3103  "You need to pay for the weapon to animate it.");
3104  return 0;
3105  }
3106  if (QUERY_FLAG(weapon, FLAG_APPLIED)) {
3107  char wn[MAX_BUF];
3108 
3109  query_name(weapon, wn, MAX_BUF);
3111  "You need to unequip %s before using it in this spell",
3112  wn);
3113  return 0;
3114  }
3115 
3116  if (weapon->nrof > 1) {
3117  tmp = object_split(weapon, 1, NULL, 0);
3118  esrv_update_item(UPD_NROF, op, weapon);
3119  weapon = tmp;
3120  }
3121 
3122  /* create the golem object */
3123  tmp = arch_to_object(spell->other_arch);
3124 
3125  /* if animated by a player, give the player control of the golem */
3126  CLEAR_FLAG(tmp, FLAG_MONSTER);
3127  SET_FLAG(tmp, FLAG_FRIENDLY);
3128  tmp->stats.exp = 0;
3129  add_friendly_object(tmp);
3130  tmp->type = GOLEM;
3131  object_set_owner(tmp, op);
3132  set_spell_skill(op, caster, spell, tmp);
3133  op->contr->ranges[range_golem] = tmp;
3134  op->contr->shoottype = range_golem;
3135  op->contr->golem_count = tmp->count;
3136 
3137  /* Give the weapon to the golem now. A bit of a hack to check the
3138  * removed flag - it should only be set if object_split() was
3139  * used above.
3140  */
3141  if (!QUERY_FLAG(weapon, FLAG_REMOVED))
3142  object_remove(weapon);
3143  object_insert_in_ob(weapon, tmp);
3144 
3145  /* To do everything necessary to let a golem use the weapon is a pain,
3146  * so instead, just set it as equipped (otherwise, we need to update
3147  * body_info, skills, etc)
3148  */
3149  SET_FLAG(tmp, FLAG_USE_WEAPON);
3150  SET_FLAG(weapon, FLAG_APPLIED);
3151  fix_object(tmp);
3152 
3153  /* There used to be 'odd' code that basically seemed to take the absolute
3154  * value of the weapon->magic an use that. IMO, that doesn't make sense -
3155  * if you're using a crappy weapon, it shouldn't be as good.
3156  */
3157 
3158  /* modify weapon's animated wc */
3159  tmp->stats.wc = tmp->stats.wc
3160  -SP_level_range_adjust(caster, spell)
3161  -5*weapon->stats.Dex
3162  -2*weapon->stats.Str
3163  -weapon->magic;
3164  if (tmp->stats.wc < -127)
3165  tmp->stats.wc = -127;
3166 
3167  /* Modify hit points for weapon */
3168  tmp->stats.maxhp = tmp->stats.maxhp
3169  +spell->duration
3170  +SP_level_duration_adjust(caster, spell)
3171  +8*weapon->magic
3172  +12*weapon->stats.Con;
3173  if (tmp->stats.maxhp < 0)
3174  tmp->stats.maxhp = 10;
3175  tmp->stats.hp = tmp->stats.maxhp;
3176 
3177  /* Modify weapon's damage */
3178  tmp->stats.dam = spell->stats.dam
3179  +SP_level_dam_adjust(caster, spell)
3180  +weapon->stats.dam
3181  +weapon->magic
3182  +5*weapon->stats.Str;
3183  if (tmp->stats.dam < 0)
3184  tmp->stats.dam = 127;
3185 
3186  /* attacktype */
3187  if (!tmp->attacktype)
3188  tmp->attacktype = AT_PHYSICAL;
3189 
3190  mt = NULL;
3191  if (op->materialname != NULL)
3192  mt = name_to_material(op->materialname);
3193  if (mt != NULL) {
3194  for (i = 0; i < NROFATTACKS; i++)
3195  tmp->resist[i] = 50-(mt->save[i]*5);
3196  a = mt->save[0];
3197  } else {
3198  for (i = 0; i < NROFATTACKS; i++)
3199  tmp->resist[i] = 5;
3200  a = 10;
3201  }
3202  /* Set weapon's immunity */
3203  tmp->resist[ATNR_CONFUSION] = 100;
3204  tmp->resist[ATNR_POISON] = 100;
3205  tmp->resist[ATNR_SLOW] = 100;
3206  tmp->resist[ATNR_PARALYZE] = 100;
3207  tmp->resist[ATNR_TURN_UNDEAD] = 100;
3208  tmp->resist[ATNR_FEAR] = 100;
3209  tmp->resist[ATNR_DEPLETE] = 100;
3210  tmp->resist[ATNR_DEATH] = 100;
3211  tmp->resist[ATNR_BLIND] = 100;
3212 
3213  /* Improve weapon's armour value according to best save vs. physical of its material */
3214 
3215  if (a > 14)
3216  a = 14;
3217  tmp->resist[ATNR_PHYSICAL] = 100-(int)((100.0-(float)tmp->resist[ATNR_PHYSICAL])/(30.0-2.0*a));
3218 
3219  /* Determine golem's speed */
3220  tmp->speed = 0.4+0.1*SP_level_range_adjust(caster, spell);
3221 
3222  if (tmp->speed > 3.33)
3223  tmp->speed = 3.33;
3224 
3225  if (!spell->race) {
3226  snprintf(buf, sizeof(buf), "animated %s", weapon->name);
3227  if (tmp->name)
3228  free_string(tmp->name);
3229  tmp->name = add_string(buf);
3230 
3231  tmp->face = weapon->face;
3232  tmp->animation_id = weapon->animation_id;
3233  tmp->anim_speed = weapon->anim_speed;
3234  tmp->last_anim = weapon->last_anim;
3235  tmp->state = weapon->state;
3236  if (QUERY_FLAG(weapon, FLAG_ANIMATE)) {
3237  SET_FLAG(tmp, FLAG_ANIMATE);
3238  } else {
3239  CLEAR_FLAG(tmp, FLAG_ANIMATE);
3240  }
3241  object_update_speed(tmp);
3242  }
3243 
3244  /* make experience increase in proportion to the strength of the summoned creature. */
3245  tmp->stats.exp *= 1+(MAX(spell->stats.maxgrace, spell->stats.sp)/caster_level(caster, spell));
3246 
3247  tmp->speed_left = -1;
3248  tmp->direction = dir;
3249  object_insert_in_map_at(tmp, m, op, 0, x, y);
3250  return 1;
3251 }
3252 
3267 int cast_change_map_lightlevel(object *op, object *caster, object *spell) {
3268  int success;
3269 
3270  if (!op->map)
3271  return 0; /* shouldnt happen */
3272 
3273  success = change_map_light(op->map, spell->stats.dam);
3274  if (!success) {
3275  if (spell->stats.dam < 0)
3277  "It can be no brighter here.");
3278  else
3280  "It can be no darker here.");
3281  }
3282  return success;
3283 }
3284 
3299 int create_aura(object *op, object *caster, object *spell) {
3300  int refresh = 0, i;
3301  object *new_aura;
3302 
3303  new_aura = arch_present_in_ob(spell->other_arch, op);
3304  if (new_aura)
3305  refresh = 1;
3306  else
3307  new_aura = arch_to_object(spell->other_arch);
3308 
3309  new_aura->duration = spell->duration+10*SP_level_duration_adjust(caster, spell);
3310  if (op->type == PLAYER)
3311  store_spell_expiry(new_aura);
3312 
3313  new_aura->stats.dam = spell->stats.dam+SP_level_dam_adjust(caster, spell);
3314 
3315  object_set_owner(new_aura, op);
3316  set_spell_skill(op, caster, spell, new_aura);
3317  new_aura->attacktype = spell->attacktype;
3318 
3319  new_aura->level = caster_level(caster, spell);
3320 
3321  /* Code below is so that auras can also provide resistances. For
3322  * example, fire shield both does damage to nearby enemies and also
3323  * provides some protection to fire. We need to use a different
3324  * FORCE object for this, as putting it in with the aura object
3325  * just puts too many meanings into that one object. Because
3326  * the duration of this force object is the same, we don't need
3327  * to set up spell expiry on it - this second object is really
3328  * an internal mechanic that should be invisible to the player.
3329  */
3330  for (i = 0; i < NROFATTACKS; i++) {
3331  if (spell->resist[i]) {
3332  int refresh1=1;
3333  object *force;
3334 
3335  force = object_present_in_ob_by_name(FORCE, spell->name, op);
3336  if (!force) {
3338  force->subtype = FORCE_CHANGE_ABILITY;
3339  free_string(force->name);
3340  force->name = add_refcount(spell->name);
3341  free_string(force->name_pl);
3342  force->name_pl = add_refcount(spell->name);
3343  refresh1=0;
3344  }
3345  force->duration = new_aura->duration;
3346  force->speed = new_aura->speed;
3347  memcpy(&force->resist, spell->resist, sizeof(spell->resist));
3348  SET_FLAG(force, FLAG_APPLIED);
3349 
3350  if (!refresh1)
3351  object_insert_in_ob(force, op);
3352  change_abil(op, new_aura);
3353  fix_object(op);
3354  break;
3355  }
3356  }
3357 
3358  if (refresh)
3360  "You recast the spell while in effect.");
3361  else
3362  object_insert_in_ob(new_aura, op);
3363  return 1;
3364 }
3365 
3381 int write_mark(object *op, object *spell, const char *msg) {
3382  char rune[HUGE_BUF];
3383  object *tmp;
3384 
3385  if (!msg || msg[0] == 0) {
3387  "Write what?");
3388  return 0;
3389  }
3390 
3391  if (strcasestr_local(msg, "endmsg")) {
3393  "Trying to cheat are we?");
3394  LOG(llevInfo, "write_rune: player %s tried to write bogus rune %s\n", op->name, msg);
3395  return 0;
3396  }
3397 
3398  if (!spell->other_arch)
3399  return 0;
3400  tmp = arch_to_object(spell->other_arch);
3401  strncpy(rune, msg, HUGE_BUF-2);
3402  rune[HUGE_BUF-2] = 0;
3403  strcat(rune, "\n");
3404  tmp->race = add_string(op->name); /*Save the owner of the rune*/
3405  object_set_msg(tmp, rune);
3406  object_insert_in_map_at(tmp, op->map, op, INS_BELOW_ORIGINATOR, op->x, op->y);
3407  return 1;
3408 }
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:695
#define FLAG_DAMNED
Definition: define.h:318
#define FLAG_IS_FLOOR
Definition: define.h:303
#define FLAG_UNPAID
Definition: define.h:236
int8_t ac
Definition: living.h:38
#define MOVE_WALK
Definition: define.h:407
#define UP_OBJ_FACE
Definition: object.h:517
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:570
int cast_bless(object *op, object *caster, object *spell_ob, int dir)
#define MSG_TYPE_ITEM
Definition: newclient.h:388
#define AT_COUNTERSPELL
Definition: attack.h:95
void object_free(object *ob, int flags)
Definition: object.c:1409
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:1237
#define ATNR_TURN_UNDEAD
Definition: attack.h:62
int cast_detection(object *op, object *caster, object *spell)
#define FOR_OB_AND_ABOVE_PREPARE(op_)
Definition: define.h:776
int caster_level(const object *caster, const object *spell)
Definition: spell_util.c:233
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:3994
#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:114
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:1815
#define MSG_TYPE_SPELL_FAILURE
Definition: newclient.h:628
int16_t maxgrace
Definition: living.h:45
void free_string(sstring str)
Definition: shstr.c:280
#define HUGE_BUF
Definition: define.h:37
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.c: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:1360
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:456
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:602
rangetype shoottype
Definition: player.h:99
Definition: object.h:240
Definition: object.h:119
const char * slaying
Definition: object.h:319
int32_t last_sp
Definition: object.h: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:326
int64_t exp
Definition: living.h:47
#define FLAG_BLESSED
Definition: define.h:378
int cast_earth_to_dust(object *op, object *caster, object *spell_ob)
Definition: spell_effect.c:848
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:531
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:3078
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:1260
method_ret ob_apply(object *op, object *applier, int aflags)
Definition: ob_methods.c:44
#define FLAG_TEAR_DOWN
Definition: define.h:279
#define AT_BLIND
Definition: attack.h:98
int16_t sp
Definition: living.h:42
const object * find_god(const char *name)
Definition: gods.c:80
#define NDI_BLACK
Definition: newclient.h:221
#define PETMOVE
Definition: define.h:519
uint32_t hidden
Definition: player.h:132
struct obj * enemy
Definition: object.h: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:791
int16_t maxsp
Definition: living.h:43
int8_t Con
Definition: living.h:36
#define MIN(x, y)
Definition: compat.h:17
int change_map_light(mapstruct *m, int change)
Definition: map.c:2007
#define FLAG_REMOVED
Definition: define.h:232
int16_t hp
Definition: living.h:40
archetype * find_archetype_by_object_type_name(int type, const char *name)
Definition: arch.c:83
int cast_cone(object *op, object *caster, int dir, object *spell)
Definition: spell_attack.c:297
short freearr_y[SIZEOFFREE]
Definition: object.c:71
#define FLAG_KNOWN_MAGICAL
Definition: define.h:320
object * active_objects
Definition: object.c:62
#define SOUND_TYPE_ITEM
Definition: newclient.h:310
#define NDI_NAVY
Definition: newclient.h:223
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:488
#define strcasestr_local
Definition: compat.h:24
void pets_control_golem(object *op, int dir)
Definition: pets.c:648
void polymorph(object *op, object *who, int level)
Definition: spell_effect.c:376
int rndm(int min, int max)
Definition: utils.c:162
void map_newmap_cmd(socket_struct *ns)
Definition: request.c:618
int probe(object *op, object *caster, object *spell_ob, int dir, int level)
Definition: spell_effect.c:683
#define FLAG_UNDEAD
Definition: define.h:270
void object_set_owner(object *op, object *owner)
Definition: object.c:632
#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:1933
int16_t maxhp
Definition: living.h:41
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:530
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:2266
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:1068
const char * name_pl
Definition: object.h:315
object * create_archetype(const char *name)
Definition: arch.c:620
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.c:95
#define FOR_OB_AND_ABOVE_FINISH()
Definition: define.h:780
#define AT_DISEASE
Definition: attack.h:102
int cast_transfer(object *op, object *caster, object *spell, int dir)
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2707
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:569
#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:854
void update_all_los(const mapstruct *map, int x, int y)
Definition: los.c:536
const char *const statname[NUM_STATS]
Definition: living.c: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:577
static void charge_mana_effect(object *victim, int caster_level)
#define SP_WONDER
Definition: spells.h:83
int cast_create_obj(object *op, object *new_op, int dir)
Definition: spell_util.c:533
object * transport
Definition: player.h:195
#define FLAG_IDENTIFIED
Definition: define.h:261
#define FOR_INV_FINISH()
Definition: define.h:714
#define MSG_TYPE_SPELL_PERCEIVE_SELF
Definition: newclient.h:632
int create_aura(object *op, object *caster, object *spell)
int SP_level_duration_adjust(const object *caster, const object *spob)
Definition: spell_util.c:351
int16_t dam
Definition: living.h:46
#define ATNR_BLIND
Definition: attack.h:71
#define MSG_TYPE_SPELL_ERROR
Definition: newclient.h:631
void add_friendly_object(object *op)
Definition: friend.c:30
Definition: object.h:145
#define FLAG_BLOCKSVIEW
Definition: define.h:269
int dimension_door(object *op, object *caster, object *spob, int dir)
const char * name
Definition: object.h:311
int16_t bed_y
Definition: player.h:98
int cast_identify(object *op, object *caster, object *spell)
int cast_wonder(object *op, object *caster, int dir, object *spell_ob)
Definition: spell_effect.c: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:3970
struct obj * below
Definition: object.h:287
#define EXIT_PATH(xyz)
Definition: define.h:455
uint64_t price_base(const object *obj)
Definition: shop.c:70
#define INS_NO_WALK_ON
Definition: object.h:568
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:36
EXTERN const char *const change_resist_msg[NROFATTACKS]
Definition: attack.h:135
#define ATNR_MAGIC
Definition: attack.h:50
#define OB_TYPE_MOVE_BLOCK(ob1, type)
Definition: define.h:447
#define UPD_FLAGS
Definition: newclient.h:290
#define FLAG_IS_CAULDRON
Definition: define.h:339
#define SIZEOFFREE
Definition: define.h:154
#define P_OUT_OF_MAP
Definition: map.h:251
#define GET_MAP_MOVE_BLOCK(M, X, Y)
Definition: map.h:192
#define EXIT_X(xyz)
Definition: define.h:457
struct pl * contr
Definition: object.h:276
#define FLAG_XRAYS
Definition: define.h:301
object * find_marked_object(object *op)
Definition: c_object.c:1266
#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:592
#define FLAG_WIZ
Definition: define.h:231
uint32_t golem_count
Definition: player.h:106
void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags)
Definition: treasure.c:1108
#define EXIT_Y(xyz)
Definition: define.h:458
#define MAX_BUF
Definition: define.h:35
char * ob_describe(const object *op, const object *observer, char *buf, size_t size)
Definition: ob_methods.c:91
struct obj * active_next
Definition: object.h:279
void give_artifact_abilities(object *op, const object *artifact)
Definition: artifact.c:203
object * object_create_arch(archetype *at)
Definition: arch.c:736
int cast_change_ability(object *op, object *caster, object *spell_ob, int dir, int silent)
int16_t x
Definition: object.h:326
static const char *const no_gain_msgs[NUM_STATS]
const char * skill
Definition: object.h:321
int8_t wc
Definition: living.h:37
#define tolower(C)
Definition: c_new.c:29
uint16_t difficulty
Definition: map.h:343
#define FOR_MAP_FINISH()
Definition: define.h:767
int8_t Str
Definition: living.h:36
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:1326
#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:2026
object * object_find_by_type_subtype(const object *who, int type, int subtype)
Definition: object.c:4215
#define AT_POISON
Definition: attack.h:86
#define FLAG_ANIMATE
Definition: define.h:242
#define PREFER_HIGH
Definition: define.h:601
uint32_t attacktype
Definition: object.h: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:2478
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:975
#define INS_NO_MERGE
Definition: object.h:566
Definition: object.h:122
int cast_consecrate(object *op, object *caster, object *spell)
int16_t grace
Definition: living.h:44
#define FREE_AND_COPY(sv, nv)
Definition: global.h:211
const char * invis_race
Definition: player.h:135
#define UPD_NROF
Definition: newclient.h:296
signed char int8_t
Definition: win32.h:158
int cast_polymorph(object *op, object *caster, object *spell_ob, int dir)
Definition: spell_effect.c:430
int SP_level_range_adjust(const object *caster, const object *spob)
Definition: spell_util.c:377
#define MAP_PLAYER_UNIQUE
Definition: map.h:97
const char * localdir
Definition: global.h: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:36
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:710
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:787
#define FLAG_STARTEQUIP
Definition: define.h:268
#define FORCE_NAME
Definition: spells.h:169
int64_t * levels
Definition: exp.c:26
#define AT_MAGIC
Definition: attack.h:77
sstring add_string(const char *str)
Definition: shstr.c:124
object * identify(object *op)
Definition: item.c:1432
#define ARCH_PORTAL_FAILED
Definition: object.h:579
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
static const int32_t MAX_FOOD
Definition: define.h:477
#define GET_MAP_OB(M, X, Y)
Definition: map.h:172
int strcasecmp(const char *s1, const char *s2)
Definition: porting.c:256
int8_t glow_radius
Definition: object.h:364
#define FLAG_MONSTER
Definition: define.h:245
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.c:869
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.c:310
struct obj * inv
Definition: object.h:290
#define NDI_UNIQUE
Definition: newclient.h:245
void counterspell(object *op, int dir)
void player_update_bg_music(object *player)
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
int makes_invisible_to(object *pl, object *mon)
Definition: spell_effect.c:740
int did_make_save(const object *op, int level, int bonus)
Definition: living.c:2225
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:760
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:98
#define P_BLOCKSVIEW
Definition: map.h:226
void object_set_msg(object *op, const char *msg)
Definition: object.c:4715
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:3432
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:623
object * item
Definition: artifact.h:15
#define LARGE_NUGGET
#define FOR_BELOW_PREPARE(op_, it_)
Definition: define.h:741
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.c:516
object * map_find_by_archetype(mapstruct *m, int x, int y, const archetype *at)
Definition: object.c:2961
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:4188
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
Definition: attack.c:1862
int16_t level
Definition: object.h:351
int8_t facing
Definition: object.h:335
void fix_object(object *op)
Definition: living.c:1119
EXTERN archetype * first_archetype
Definition: global.h:122
struct obj * more
Definition: object.h:295
object * arch_to_object(archetype *at)
Definition: arch.c:571
void object_update_speed(object *op)
Definition: object.c:1150
int32_t value
Definition: object.h:350
object * object_get_owner(object *op)
Definition: object.c:590
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:748
#define HAS_RANDOM_ITEMS(op)
Definition: define.h:183
object * object_present_in_ob_by_name(int type, const char *str, const object *op)
Definition: object.c:3056
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:707
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Definition: spell_util.c:1469
void object_remove(object *op)
Definition: object.c:1666
struct artifactstruct * next
Definition: artifact.h:18
int atnr_is_dragon_enabled(int attacknr)
Definition: player.c:95
int32_t food
Definition: living.h:48
static bool CAN_PROBE(const object *ob)
Definition: object.h:601
uint32_t count
Definition: player.h:109
Definition: object.h:224