Crossfire Server, Trunk
spell_util.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "global.h"
20 
21 #include <assert.h>
22 #include <ctype.h>
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "living.h"
28 #include "object.h"
29 #include "sounds.h"
30 #include "spells.h"
31 #include "sproto.h"
32 #include "assets.h"
33 #include "AssetsManager.h"
34 
48 object *find_random_spell_in_ob(object *ob, const char *skill) {
49  int k = 0, s;
50 
52  if (tmp->type == SPELL && (!skill || tmp->skill == skill))
53  k++;
55 
56  /* No spells, no need to progess further */
57  if (!k)
58  return NULL;
59 
60  s = RANDOM()%k;
62  if (tmp->type == SPELL && (!skill || tmp->skill == skill)) {
63  if (!s)
64  return tmp;
65  else
66  s--;
67  }
69 
70  /* Should never get here, but just in case */
71  return NULL;
72 }
73 
94 void set_spell_skill(object *op, object *caster, object *spob, object *dest) {
95  if (dest->skill)
96  FREE_AND_CLEAR_STR(dest->skill);
97  if (caster == op && spob->skill)
98  dest->skill = add_refcount(spob->skill);
99  else if (caster->skill)
100  dest->skill = add_refcount(caster->skill);
101 }
102 
108 void dump_spells(void) {
109  int banner = 0;
110 
111  getManager()->archetypes()->each([] (const auto at) {
112  if (at->clone.type == SPELL) {
113  fprintf(stderr, "%s:%s:%s:%s:%d\n", at->clone.name ? at->clone.name : "null",
114  at->name, at->clone.other_arch ? at->clone.other_arch->name : "null",
115  at->clone.skill ? at->clone.skill : "null", at->clone.level);
116  }
117  });
118 
119  getManager()->archetypes()->each([&] (const auto at) {
120  if (at->clone.type == SPELL && at->clone.path_attuned == 0) {
121  if (banner == 0) {
122  banner = 1;
123  fprintf(stderr, "Spells with no path set:\n");
124  }
125 
126  fprintf(stderr, "- %s\n", at->clone.name ? at->clone.name : "null");
127  }
128  });
129 }
130 
144 void spell_effect(object *spob, int x, int y, mapstruct *map, object *originator) {
145  if (spob->other_arch != NULL) {
146  object *effect = arch_to_object(spob->other_arch);
147  object_insert_in_map_at(effect, map, originator, 0, x, y);
148  }
149 }
150 
164 int min_casting_level(const object *caster, const object *spell) {
165  int new_level;
166 
167  if (caster->path_denied&spell->path_attuned) {
168  /* This case is not a bug, just the fact that this function is
169  * usually called BEFORE checking for path_deny. -AV
170  */
171  return 1;
172  }
173  new_level = spell->level
174  +((caster->path_repelled&spell->path_attuned) ? +2 : 0)
175  +((caster->path_attuned&spell->path_attuned) ? -2 : 0);
176  return MAX(new_level, 1);
177 }
178 
179 
194 int caster_level(const object *caster, const object *spell) {
195  int level = caster->level;
196 
197  /* If this is a player, try to find the matching skill */
198  if (caster->type == PLAYER && spell->skill) {
199  object* skill = find_applied_skill_by_name(caster, spell->skill);
200  if (skill != NULL) {
201  level = skill->level;
202  } else {
203  level = 0;
204  }
205  }
206  /* Got valid caster level. Now adjust for attunement */
207  level += ((caster->path_repelled&spell->path_attuned) ? -2 : 0)
208  +((caster->path_attuned&spell->path_attuned) ? 2 : 0);
209 
210  /* Always make this at least 1. If this is zero, we get divide by zero
211  * errors in various places.
212  */
213  if (level < 1)
214  level = 1;
215  return level;
216 }
217 
236 int16_t SP_level_spellpoint_cost(object *caster, object *spell, int flags) {
237  int sp, grace, level = caster_level(caster, spell);
238 
240  if (spell->stats.sp && spell->stats.maxsp) {
241  sp = (int)(spell->stats.sp*(1.0+MAX(0, (float)(level-spell->level)/(float)spell->stats.maxsp)));
242  } else
243  sp = spell->stats.sp;
244 
245  sp *= PATH_SP_MULT(caster, spell);
246  if (!sp && spell->stats.sp)
247  sp = 1;
248 
249  if (spell->stats.grace && spell->stats.maxgrace) {
250  grace = (int)(spell->stats.grace*(1.0+MAX(0, (float)(level-spell->level)/(float)spell->stats.maxgrace)));
251  } else
252  grace = spell->stats.grace;
253 
254  grace *= PATH_SP_MULT(caster, spell);
255  if (spell->stats.grace && !grace)
256  grace = 1;
257  } else {
258  sp = spell->stats.sp*PATH_SP_MULT(caster, spell);
259  if (spell->stats.sp && !sp)
260  sp = 1;
261  grace = spell->stats.grace*PATH_SP_MULT(caster, spell);
262  if (spell->stats.grace && !grace)
263  grace = 1;
264  }
265  if (flags == SPELL_HIGHEST)
266  return MAX(sp, grace);
267  else if (flags == SPELL_GRACE)
268  return grace;
269  else if (flags == SPELL_MANA)
270  return sp;
271  else {
272  LOG(llevError, "SP_level_spellpoint_cost: Unknown flags passed: %d\n", flags);
273  return 0;
274  }
275 }
276 
287 int SP_level_dam_adjust(const object *caster, const object *spob) {
288  int level = caster_level(caster, spob);
289  int adj = level-min_casting_level(caster, spob);
290 
291  if (adj < 0)
292  adj = 0;
293  if (spob->dam_modifier)
294  adj /= spob->dam_modifier;
295  else
296  adj = 0;
297  return adj;
298 }
299 
312 int SP_level_duration_adjust(const object *caster, const object *spob) {
313  int level = caster_level(caster, spob);
314  int adj = level-min_casting_level(caster, spob);
315 
316  if (adj < 0)
317  adj = 0;
318  if (spob->duration_modifier)
319  adj /= spob->duration_modifier;
320  else
321  adj = 0;
322 
323  return adj;
324 }
325 
338 int SP_level_range_adjust(const object *caster, const object *spob) {
339  int level = caster_level(caster, spob);
340  int adj = level-min_casting_level(caster, spob);
341 
342  if (adj < 0)
343  adj = 0;
344  if (spob->range_modifier)
345  adj /= spob->range_modifier;
346  else
347  adj = 0;
348 
349  return adj;
350 }
351 
362 int SP_level_wc_adjust(const object *caster, const object *spob) {
363  int level = caster_level(caster, spob);
364  int adj = level - min_casting_level(caster, spob), irate;
365  sstring rate;
366 
367  rate = object_get_value(spob, "wc_increase_rate");
368 
369  if (rate == NULL)
370  return 0;
371 
372  if (adj < 0)
373  adj = 0;
374 
375  irate = atoi(rate);
376  if (irate > 0)
377  adj /= irate;
378  else
379  adj = 0;
380  return adj;
381 }
382 
394 object *check_spell_known(object *op, const char *name) {
396 }
397 
410 object *lookup_spell_by_name(object *op, const char *spname) {
411  object *spob1 = NULL, *spob2 = NULL;
412  int nummatch = 0;
413 
414  if (spname == NULL)
415  return NULL;
416 
417  /* Try to find the spell. We store the results in spob1
418  * and spob2 - spob1 is only taking the length of
419  * the past spname, spob2 uses the length of the spell name.
420  */
421  FOR_INV_PREPARE(op, spob) {
422  if (spob->type == SPELL) {
423  if (!strncmp(spob->name, spname, strlen(spname))) {
424  if (strlen(spname) == strlen(spob->name))
425  /* Perfect match, return it. */
426  return spob;
427  nummatch++;
428  spob1 = spob;
429  } else if (!strncmp(spob->name, spname, strlen(spob->name))) {
430  /* if spells have ambiguous names, it makes matching
431  * really difficult. (eg, fire and fireball would
432  * fall into this category). It shouldn't be hard to
433  * make sure spell names don't overlap in that fashion.
434  */
435  if (spob2)
436  LOG(llevError, "Found multiple spells with overlapping base names: %s, %s\n", spob2->name, spob->name);
437  spob2 = spob;
438  }
439  }
440  } FOR_INV_FINISH();
441  /* if we have best match, return it. Otherwise, if we have one match
442  * on the loser match, return that, otehrwise null
443  */
444  if (spob2)
445  return spob2;
446  if (spob1 && nummatch == 1)
447  return spob1;
448  return NULL;
449 }
450 
470 int reflwall(mapstruct *m, int x, int y, object *sp_op) {
471  if (OUT_OF_REAL_MAP(m, x, y))
472  return 0;
473  FOR_MAP_PREPARE(m, x, y, op)
475  && (!QUERY_FLAG(op, FLAG_ALIVE) || (rndm(0, 99)) < 90-(sp_op->level/10)))
476  return 1;
477  FOR_MAP_FINISH();
478  return 0;
479 }
480 
494 int cast_create_obj(object *op, object *new_op, int dir) {
495  mapstruct *m;
496  int16_t sx, sy;
497 
498  if (dir
499  && ((get_map_flags(op->map, &m, op->x+freearr_x[dir], op->y+freearr_y[dir], &sx, &sy)&P_OUT_OF_MAP)
500  || OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy)))) {
502  "Something is in the way. You cast it at your feet.");
503  dir = 0;
504  }
505  if (dir == 0)
506  object_insert_in_map_at(new_op, op->map, op, INS_BELOW_ORIGINATOR, op->x+freearr_x[dir], op->y+freearr_y[dir]);
507  else
508  object_insert_in_map_at(new_op, op->map, op, 0, op->x+freearr_x[dir], op->y+freearr_y[dir]);
509  return dir;
510 }
511 
530 int ok_to_put_more(mapstruct *m, int16_t x, int16_t y, object *op, uint32_t immune_stop) {
531  int mflags;
532  mapstruct *mp;
533 
534  mp = m;
535  mflags = get_map_flags(m, &mp, x, y, &x, &y);
536 
537  if (mflags&P_OUT_OF_MAP)
538  return 0;
539 
541  return 0;
542 
543  FOR_MAP_PREPARE(mp, x, y, tmp) {
544  /* If there is a counterspell on the space, and this
545  * object is using magic, don't progess. I believe we could
546  * leave this out and let in progress, and other areas of the code
547  * will then remove it, but that would seem to to use more
548  * resources, and may not work as well if a player is standing
549  * on top of a counterwall spell (may hit the player before being
550  * removed.) On the other hand, it may be more dramatic for the
551  * spell to actually hit the counterwall and be sucked up.
552  */
553  if ((tmp->attacktype&AT_COUNTERSPELL)
554  && (tmp->type != PLAYER)
556  && (tmp->type != WEAPON)
557  && (tmp->type != BOW)
558  && (tmp->type != ARROW)
559  && (tmp->type != GOLEM)
560  && (immune_stop&AT_MAGIC))
561  return 0;
562 
563  /* This is to prevent 'out of control' spells. Basically, this
564  * limits one spell effect per space per spell. This is definitely
565  * needed for performance reasons, and just for playability I believe.
566  * there are no such things as multispaced spells right now, so
567  * we don't need to worry about the head.
568  * We only need to go down this path is maxhp is set on both objects -
569  * otherwise, no reason to check. But if we do check, we need to
570  * do some extra work, looking in the spell_tags[] of each object,
571  * if they have it set.
572  */
573  if (tmp->type == op->type
574  && tmp->subtype == op->subtype
575  && tmp->stats.maxhp
576  && op->stats.maxhp) {
577  if ((tmp->stats.maxhp == op->stats.maxhp)
578  || (tmp->spell_tags && OB_SPELL_TAG_MATCH(tmp, (tag_t)op->stats.maxhp))
579  || (op->spell_tags && OB_SPELL_TAG_MATCH(op, (tag_t)tmp->stats.maxhp))) {
581  return 0;
582  }
583 
584  /* if both objects have spell tags, then if the two tags entries
585  * from either match, that also counts. Need to check
586  * the spell_tags, because 0 values are allowed to match
587  */
588  if (op->spell_tags && tmp->spell_tags) {
589  int i;
590 
591  for (i = 0; i < SPELL_TAG_SIZE; i++) {
592  if (op->spell_tags[i] &&
593  op->spell_tags[i] == tmp->spell_tags[i]) {
595  return 0;
596  }
597  }
598  }
599  }
600  /* Perhaps we should also put checks in for no magic and unholy
601  * ground to prevent it from moving along?
602  */
603  } FOR_MAP_FINISH();
604  /* If it passes the above tests, it must be OK */
605  return 1;
606 }
607 
629 int fire_arch_from_position(object *op, object *caster, int16_t x, int16_t y, int dir, object *spell) {
630  object *tmp;
631  int mflags;
632  mapstruct *m;
633 
634  if (dir < 0 || dir > 8) {
635  LOG(llevError, "Invalid direction %d in fire_arch_from_position for %s\n", dir, spell->name);
636  dir = RANDOM() % 8 + 1;
637  }
638 
639  if (spell->other_arch == NULL)
640  return 0;
641 
642  if (spell->type != SPELL)
643  LOG(llevError, "Unexpected object type %d in fire_arch_from_position for %s\n", spell->type, spell->name);
644 
645  m = op->map;
646  mflags = get_map_flags(m, &m, x, y, &x, &y);
647  if (mflags&P_OUT_OF_MAP) {
648  return 0;
649  }
650 
651  tmp = arch_to_object(spell->other_arch);
652  if (tmp == NULL)
653  return 0;
654 
655  mflags = get_map_flags(m, &tmp->map, x, y, &tmp->x, &tmp->y);
656  if (mflags&P_OUT_OF_MAP) {
658  return 0;
659  }
660 
661  if (spell->subtype == SP_BULLET) {
662  /* peterm: level dependency for bolts */
663  tmp->stats.dam = spell->stats.dam+SP_level_dam_adjust(caster, spell);
664  tmp->attacktype = spell->attacktype;
665  if (spell->slaying)
666  tmp->slaying = add_refcount(spell->slaying);
667 
668  tmp->range = 50;
669 
670  /* Need to store duration/range for the ball to use */
671  tmp->stats.hp = spell->duration+SP_level_duration_adjust(caster, spell);
672  tmp->stats.maxhp = spell->range+SP_level_range_adjust(caster, spell);
673  tmp->dam_modifier = spell->stats.food+SP_level_dam_adjust(caster, spell);
674 
675  tmp->direction = dir;
677 
679  } else {
680  if (spell->subtype != SP_MAGIC_MISSILE && spell->subtype != SP_MOVING_BALL)
681  LOG(llevError, "Unexpected object subtype %d in fire_arch_from_position for %s\n", spell->subtype, spell->name);
682 
683  /*
684  * Things like firewalls and such can fire even if blocked, since the
685  * origin is themselves which block things...
686  * This fixes bug #3536508.
687  */
688  if (caster->type == PLAYER && OB_TYPE_MOVE_BLOCK(tmp, GET_MAP_MOVE_BLOCK(tmp->map, tmp->x, tmp->y))) {
690  "You can't cast the spell on top of a wall!");
692  return 0;
693  }
694 
695  tmp->stats.dam = spell->stats.dam+SP_level_dam_adjust(caster, spell);
696  tmp->duration = spell->duration+SP_level_duration_adjust(caster, spell);
697  /* code in time.c uses food for some things, duration for others */
698  tmp->stats.food = tmp->duration;
699  tmp->range = spell->range+SP_level_range_adjust(caster, spell);
700  tmp->attacktype = spell->attacktype;
701  if (object_get_owner(op) != NULL)
703  else
705  tmp->level = caster_level(caster, spell);
706  }
707 
708  tmp->direction = dir;
709  set_spell_skill(op, caster, spell, tmp);
710 
711  if (spell->subtype == SP_BULLET) {
712  if (OB_TYPE_MOVE_BLOCK(tmp, GET_MAP_MOVE_BLOCK(tmp->map, tmp->x, tmp->y))) {
713  if (!QUERY_FLAG(tmp, FLAG_REFLECTING)) {
715  return 0;
716  }
717  tmp->direction = absdir(tmp->direction+4);
718  x += DIRX(tmp);
719  y += DIRY(tmp);
720  mflags = get_map_flags(m, &m, x, y, &x, &y);
721  if (mflags&P_OUT_OF_MAP) {
723  return 0;
724  }
725  tmp->x = x;
726  tmp->y = y;
727  tmp->map = m;
728  }
729 
730  tmp = object_insert_in_map_at(tmp, tmp->map, op, 0, tmp->x, tmp->y);
731  if (tmp != NULL)
732  check_bullet(tmp);
733  } else /*if (spell->subtype == SP_MAGIC_MISSILE || spell->subtype == SP_MOVING_BALL) */ {
734  /* needed for AT_HOLYWORD, AT_GODPOWER stuff */
735  if (tmp->attacktype&AT_HOLYWORD || tmp->attacktype&AT_GODPOWER) {
736  if (!tailor_god_spell(tmp, op))
737  return 0;
738  }
740 
741  tmp = object_insert_in_map_at(tmp, tmp->map, op, 0, tmp->x, tmp->y);
742  if (tmp != NULL)
743  ob_process(tmp);
744  }
745 
746  return 1;
747 }
748 
749 /*****************************************************************************
750  *
751  * Code related to rods - perhaps better located in another file?
752  *
753  ****************************************************************************/
754 
761 void regenerate_rod(object *rod) {
762  if (rod->stats.hp < rod->stats.maxhp) {
763  rod->stats.hp += 1+rod->stats.maxhp/10;
764 
765  if (rod->stats.hp > rod->stats.maxhp)
766  rod->stats.hp = rod->stats.maxhp;
767  }
768 }
769 
776 void drain_rod_charge(object *rod) {
777  rod->stats.hp -= SP_level_spellpoint_cost(rod, rod->inv, SPELL_HIGHEST);
778 }
779 
786 void drain_wand_charge(object *wand) {
787  assert(wand->type == WAND);
788 
789  if (!(--wand->stats.food)) {
790  object *tmp;
791  if (wand->arch) {
792  CLEAR_FLAG(wand, FLAG_ANIMATE);
793  wand->face = wand->arch->clone.face;
794  wand->speed = 0;
795  object_update_speed(wand);
796  }
798  if (tmp)
799  esrv_update_item(UPD_ANIM, tmp, wand);
800  }
801 }
802 
813 object *find_target_for_friendly_spell(object *op, int dir) {
814  object *tmp;
815  mapstruct *m;
816  int16_t x, y;
817  int mflags;
818 
819  /* I don't really get this block - if op isn't a player or rune,
820  * we then make the owner of this object the target.
821  * The owner could very well be no where near op.
822  */
823  if (op->type != PLAYER && op->type != RUNE) {
825  /* If the owner does not exist, or is not a monster, than apply the spell
826  * to the caster.
827  */
828  if (!tmp || !QUERY_FLAG(tmp, FLAG_MONSTER))
829  tmp = op;
830  } else {
831  m = op->map;
832  x = op->x+freearr_x[dir];
833  y = op->y+freearr_y[dir];
834 
835  mflags = get_map_flags(m, &m, x, y, &x, &y);
836 
837  if (mflags&P_OUT_OF_MAP)
838  tmp = NULL;
839  else {
840  for (tmp = GET_MAP_OB(m, x, y); tmp != NULL; tmp = tmp->above) {
841  if (tmp->type == PLAYER)
842  break;
843  }
844  }
845  }
846  /* didn't find a player there, look in current square for a player */
847  if (tmp == NULL) {
848  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp) {
849  if (tmp->type == PLAYER)
850  return tmp;
851  /* Don't forget to browse inside transports ! - gros 2006/07/25 */
852  if (tmp->type == TRANSPORT) {
853  object *inv;
854 
855  for (inv = tmp->inv; inv; inv = inv->below) {
856  if ((inv->type == PLAYER) && (op == inv))
857  return inv;
858  }
859  }
860  } FOR_MAP_FINISH();
861  }
862  return tmp;
863 }
864 
865 
866 
887 int spell_find_dir(mapstruct *m, int x, int y, object *exclude) {
888  int i;
889  int16_t nx, ny;
890  int owner_type = 0, mflags;
891  object *tmp;
892  mapstruct *mp;
893  int dirs[SIZEOFFREE];
894 
895  if (exclude != NULL) {
896  exclude = HEAD(exclude);
897  owner_type = exclude->type;
898  }
899 
900  get_search_arr(dirs);
901  for (i = 1; i < SIZEOFFREE; i++) {
902  nx = x+freearr_x[dirs[i]];
903  ny = y+freearr_y[dirs[i]];
904  mp = m;
905  mflags = get_map_flags(m, &mp, nx, ny, &nx, &ny);
906  if (mflags&(P_OUT_OF_MAP|P_BLOCKSVIEW))
907  continue;
908 
909  for (tmp = GET_MAP_OB(mp, nx, ny); tmp != NULL; tmp = tmp->above) {
910  object *head;
911 
912  head = HEAD(tmp);
913  if ((owner_type != PLAYER || QUERY_FLAG(head, FLAG_MONSTER) || QUERY_FLAG(head, FLAG_GENERATOR) || (head->type == PLAYER && op_on_battleground(head, NULL, NULL, NULL)))
914  && (owner_type == PLAYER || head->type == PLAYER)
915  && head != exclude
916  && can_see_monsterP(m, x, y, dirs[i])) {
917  return freedir[dirs[i]];
918  }
919  }
920  }
921  return -1; /* flag for "keep going the way you were" */
922 }
923 
924 
925 
939 static int put_a_monster(object *op, const char *monstername) {
940  object *tmp, *head = NULL, *prev = NULL;
941  archetype *at;
942  int dir;
943 
944  /* Handle cases where we are passed a bogus mosntername */
945  at = try_find_archetype(monstername);
946  if (at == NULL)
947  return 0;
948 
949  /* find a free square nearby
950  * first we check the closest square for free squares
951  */
952 
953  dir = object_find_first_free_spot(&at->clone, op->map, op->x, op->y);
954  if (dir != -1) {
955  /* This is basically grabbed for generate monster. Fixed 971225 to
956  * insert multipart monsters properly
957  */
958  while (at != NULL) {
959  tmp = arch_to_object(at);
960  tmp->x = op->x+freearr_x[dir]+at->clone.x;
961  tmp->y = op->y+freearr_y[dir]+at->clone.y;
962  tmp->map = op->map;
963  if (head) {
964  tmp->head = head;
965  prev->more = tmp;
966  }
967  if (!head)
968  head = tmp;
969  prev = tmp;
970  at = at->more;
971  }
972 
973  if (head->randomitems)
974  create_treasure(head->randomitems, head, GT_INVISIBLE, op->map->difficulty, 0);
975 
976  object_insert_in_map_at(head, op->map, op, 0, op->x, op->y);
977 
978  /* thought it'd be cool to insert a burnout, too.*/
979  tmp = create_archetype("burnout");
980  object_insert_in_map_at(tmp, op->map, op, 0, op->x+freearr_x[dir], op->y+freearr_y[dir]);
981  return 1;
982  } else {
983  return 0;
984  }
985 }
986 
1005 int summon_hostile_monsters(object *op, int n, const char *monstername) {
1006  int i, put = 0;
1007 
1008  for (i = 0; i < n; i++)
1009  put += put_a_monster(op, monstername);
1010 
1011  return put;
1012 }
1013 
1014 
1033 void shuffle_attack(object *op) {
1034  int i;
1035 
1036  i = rndm(0, 21);
1037  op->attacktype = ATTACKS[i].attacktype|AT_MAGIC;
1038  SET_ANIMATION(op, ATTACKS[i].face);
1039 }
1040 
1041 
1052 static void prayer_failure(object *op, int failure, int power) {
1053  const char *godname;
1054  object *tmp;
1055 
1056  godname = determine_god(op);
1057  if (!strcmp(godname, "none"))
1058  godname = "Your spirit";
1059 
1060  if (failure <= -20 && failure > -40) { /* wonder */
1062  "%s gives a sign to renew your faith.",
1063  godname);
1065  cast_cone(op, op, 0, tmp);
1067  } else if (failure <= -40 && failure > -60) { /* confusion */
1069  "Your diety touches your mind!");
1070  confuse_living(op, op, 99);
1071  } else if (failure <= -60 && failure > -150) { /* paralysis */
1073  "%s requires you to pray NOW. You comply, ignoring all else.",
1074  godname);
1075 
1076  paralyze_living(op, 99);
1077  } else if (failure <= -150) { /* blast the immediate area */
1080  "%s smites you!",
1081  godname);
1082  /* Put a cap on power - this is effectively cost of the spell minus
1083  * characters current grace. Thus, if spell costs 30 grace and
1084  * character has -100 grace, this is cast as a level 130 spell.
1085  * Things start to break in those cases.
1086  */
1087  cast_magic_storm(op, tmp, power > 50 ? 50 : power);
1088  }
1089 }
1090 
1103 void spell_failure(object *op, int failure, int power, object *skill) {
1104  object *tmp;
1105 
1107  return;
1108 
1109  if (failure <= -20 && failure > -40) { /* wonder */
1111  "Your spell causes an unexpected effect.");
1113  cast_cone(op, op, 0, tmp);
1115  } else if (failure <= -40 && failure > -60) { /* confusion */
1117  "Your magic recoils on you, making you confused!");
1118  confuse_living(op, op, 99);
1119  } else if (failure <= -60 && failure > -80) { /* paralysis */
1121  "Your magic stuns you!");
1122  paralyze_living(op, 99);
1123  } else if (failure <= -80) { /* blast the immediate area */
1124  object *tmp;
1125 
1126  /* Safety check to make sure we don't get any mana storms in scorn */
1127  if (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL)&P_NO_MAGIC) {
1129  "The magic warps and you are turned inside out!");
1130  hit_player(op, 9998, op, AT_INTERNAL, 1);
1131  } else {
1133  "You lose control of the mana! The uncontrolled magic blasts you!");
1135  tmp->level = skill->level;
1136 
1137  /* increase the area of destruction a little for more powerful spells */
1138  tmp->range += isqrt(power);
1139 
1140  if (power > 25)
1141  tmp->stats.dam = 25+isqrt(power);
1142  else
1143  tmp->stats.dam = power; /* nasty recoils! */
1144 
1145  tmp->stats.maxhp = tmp->count;
1146  if (tmp->stats.maxhp == 0)
1147  tmp->stats.maxhp = 1;
1148  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
1149  }
1150  }
1151 }
1152 
1161 static int can_be_transmuted_to_flower(object *op) {
1162  if (op->invisible)
1163  return 0;
1164 
1165  if (op->type == POTION || op->type == SCROLL || op->type == WAND || op->type == ROD || op->type == WEAPON)
1166  return 1;
1167 
1168  return 0;
1169 }
1170 
1183 static void transmute_item_to_flower(object *op) {
1184  object *force;
1185  object *item;
1186  object *flower;
1187  object *first = NULL;
1188  int count = 0;
1189  char name[HUGE_BUF];
1190 
1193  if (!first)
1194  first = item;
1195  count++;
1196  }
1197  FOR_INV_FINISH();
1198 
1199  if (count == 0)
1200  return;
1201 
1202  count = rndm(0, count-1);
1203  for (item = first; item; item = item->below) {
1205  count--;
1206  if (count < 0)
1207  break;
1208  }
1209  }
1210 
1211  if (!item)
1212  return;
1213 
1215  force->duration = 100+rndm(0, 10)*100;
1216  force->subtype = FORCE_TRANSFORMED_ITEM;
1217  force->speed = 1;
1219 
1220  flower = create_archetype("flowers_permanent");
1221 
1225  SET_FLAG(flower, FLAG_STARTEQUIP);
1226  }
1228  flower->weight = item->nrof ? ((int32_t)item->nrof)*item->weight : item->weight;
1229  item->weight = 0;
1230  esrv_del_item(op->contr, item);
1232 
1236  "Your %s turns to a flower!",
1237  name);
1238 
1239  object_insert_in_ob(force, flower);
1240  flower = object_insert_in_ob(flower, op);
1241  esrv_send_item(op, flower);
1242 }
1243 
1254 static void swap_random_stats(object *op) {
1255  object *force;
1256  int first, second;
1257 
1258  first = RANDOM()%NUM_STATS;
1259  second = RANDOM()%(NUM_STATS-1);
1260  if (second >= first)
1261  second++;
1262 
1265  "You suddenly feel really weird!");
1266 
1268  force->duration = 100+rndm(0, 10)*100;
1269  force->speed = 1;
1271  set_attr_value(&force->stats, second, get_attr_value(&op->stats, first)-get_attr_value(&op->stats, second));
1272  set_attr_value(&force->stats, first, get_attr_value(&op->stats, second)-get_attr_value(&op->stats, first));
1275  change_abil(op, force);
1276  fix_object(op);
1277 }
1278 
1289 static void handle_spell_confusion(object *op) {
1290  switch (RANDOM()%2) {
1291  case 0:
1293  break;
1294 
1295  case 1:
1297  break;
1298  }
1299 }
1300 
1308 static int spell_consume_items(object *op, const object *spell_ob) {
1309  sstring requirements;
1310  char *copy;
1311  char *ingredients[10];
1312  object *found[10];
1313  int count, i;
1314  uint32_t nrof[10];
1315  char name_ob[MAX_BUF];
1316  const char *name2;
1317 
1318  if (op->type != PLAYER)
1319  return 1;
1320 
1321  requirements = object_get_value(spell_ob, "casting_requirements");
1322  if (!requirements)
1323  /* no special requirements */
1324  return 1;
1325 
1326  /* find items */
1327  copy = strdup_local(requirements);
1328  count = split_string(copy, ingredients, 10, ',');
1329 
1330  /* first pass, find items */
1331  for (i = 0; i < count; i++) {
1332  nrof[i] = 0;
1333  found[i] = NULL;
1334  while (isdigit(*ingredients[i])) {
1335  nrof[i] = 10*nrof[i]+(*(ingredients[i])-'0');
1336  ingredients[i]++;
1337  }
1338  if (nrof[i] == 0)
1339  nrof[i] = 1;
1340  while (*ingredients[i] == ' ')
1341  ingredients[i]++;
1342 
1343  /* now find item in op's inv */
1345 
1346  if (check->title == NULL)
1347  name2 = check->name;
1348  else {
1349  snprintf(name_ob, sizeof(name_ob), "%s %s", check->name, check->title);
1350  name2 = name_ob;
1351  }
1352 
1353  if (strcmp(name2, ingredients[i]) == 0) {
1354  found[i] = check;
1355  break;
1356  }
1357  } FOR_INV_FINISH();
1358 
1359  if (found[i] == NULL) {
1362  "Casting this spell requires %s, but you don't have any.",
1363  ingredients[i]);
1364  free(copy);
1365  return 0;
1366  }
1367 
1368  if (found[i]->nrof < nrof[i]) {
1371  "Casting this spell requires %d %s, but you only have %d.",
1372  nrof[i], found[i]->name_pl, found[i]->nrof);
1373  free(copy);
1374  return 0;
1375  }
1376  }
1377 
1378  free(copy);
1379 
1380  /* ok, found ingredients, remove'em */
1381  for (i = 0; i < count; i++) {
1382  object_decrease_nrof(found[i], nrof[i]);
1383  }
1384 
1385  /* all right, spell can be cast */
1386  return 1;
1387 }
1388 
1424 int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg) {
1425  const char *godname;
1426  int success = 0, mflags, cast_level = 0;
1427  rangetype old_shoottype;
1428  object *skill = NULL;
1429  int confusion_effect = 0;
1430  float cost_multiplier = 1.0f;
1431 
1432  old_shoottype = op->contr ? op->contr->shoottype : range_none;
1433 
1434  if (!spell_ob) {
1435  LOG(llevError, "cast_spell: null spell object passed\n");
1436  return 0;
1437  }
1438  godname = determine_god(op);
1439  if (!strcmp(godname, "none"))
1440  godname = "A random spirit";
1441 
1442  /* the caller should set caster to op if appropriate */
1443  if (!caster) {
1444  LOG(llevError, "cast_spell: null caster object passed\n");
1445  return 0;
1446  }
1447  if (spell_ob->anim_suffix)
1448  apply_anim_suffix(caster, spell_ob->anim_suffix);
1449 
1450  /* Handle some random effect if confused. */
1451  if (QUERY_FLAG(op, FLAG_CONFUSED) && caster == op && op->type == PLAYER) {
1452  if (rndm(0, 5) < 4) {
1453  spell_ob = find_random_spell_in_ob(op, NULL);
1456  "In your confused state, you're not sure of what you cast!");
1457  } else
1458  /* We fall through to deplate sp/gr, and do some checks. */
1459  confusion_effect = 1;
1460  }
1461 
1462  /* if caster is a spell casting object, this normally shouldn't be
1463  * an issue, because they don't have any spellpaths set up.
1464  */
1465  if ((caster->path_denied&spell_ob->path_attuned) && !QUERY_FLAG(caster, FLAG_WIZ)) {
1467  "That spell path is denied to you.");
1468  return 0;
1469  }
1470 
1471 
1472  mflags = get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL);
1473 
1474  /* See if we can cast a spell here. If the caster and op are
1475  * not alive, then this would mean that the mapmaker put the
1476  * objects on the space - presume that they know what they are
1477  * doing.
1478  */
1479  if (spell_ob->type == SPELL
1480  && caster->type != POTION
1481  && !QUERY_FLAG(op, FLAG_WIZCAST)
1482  && (QUERY_FLAG(caster, FLAG_ALIVE) || QUERY_FLAG(op, FLAG_ALIVE))
1483  && !QUERY_FLAG(op, FLAG_MONSTER)
1484  && (((mflags&P_NO_MAGIC) && spell_ob->stats.sp) || ((mflags&P_NO_CLERIC) && spell_ob->stats.grace))) {
1485  if (op->type != PLAYER)
1486  return 0;
1487 
1489 
1490  if ((mflags&P_NO_CLERIC) && spell_ob->stats.grace)
1492  "This ground is unholy! %s ignores you.",
1493  godname);
1494  else
1495  switch (op->contr->shoottype) {
1496  case range_magic:
1498  "Something blocks your spellcasting.");
1499  break;
1500 
1501  case range_misc:
1503  "Something blocks the magic of your item.");
1504  break;
1505  case range_golem:
1507  "Something blocks the magic of your scroll.");
1508  break;
1509 
1510  default:
1511  break;
1512  }
1513  return 0;
1514  }
1515 
1516  /* if it is a player casting the spell, and they are really casting it
1517  * (vs it coming from a wand, scroll, or whatever else), do some
1518  * checks. We let monsters do special things - eg, they
1519  * don't need the skill, bypass level checks, etc. The monster function
1520  * should take care of that.
1521  * Remove the wiz check here and move it further down - some spells
1522  * need to have the right skill pointer passed, so we need to
1523  * at least process that code.
1524  */
1525  if (op->type == PLAYER && op == caster) {
1526  cast_level = caster_level(caster, spell_ob);
1527  if (spell_ob->skill) {
1528  skill = find_skill_by_name(op, spell_ob->skill);
1529  if (!skill) {
1532  "You need the skill %s to cast %s.",
1533  spell_ob->skill, spell_ob->name);
1534  return 0;
1535  }
1536  if (min_casting_level(op, spell_ob) > cast_level && !QUERY_FLAG(op, FLAG_WIZ)) {
1538  "You lack enough skill to cast that spell.");
1539  return 0;
1540  }
1541  }
1542  /* If the caster is the wiz, they don't ever fail, and don't have
1543  * to have sufficient grace/mana.
1544  */
1545  if (!QUERY_FLAG(op, FLAG_WIZ)) {
1546  if (SP_level_spellpoint_cost(caster, spell_ob, SPELL_MANA)
1547  && SP_level_spellpoint_cost(caster, spell_ob, SPELL_MANA) > op->stats.sp) {
1549  "You don't have enough mana.");
1550  return 0;
1551  }
1552  if (SP_level_spellpoint_cost(caster, spell_ob, SPELL_GRACE)
1553  && SP_level_spellpoint_cost(caster, spell_ob, SPELL_GRACE) > op->stats.grace) {
1554  if (random_roll(0, op->stats.Wis-1, op, PREFER_HIGH)+op->stats.grace-10*SP_level_spellpoint_cost(caster, spell_ob, SPELL_GRACE)/op->stats.maxgrace > 0) {
1557  "%s grants your prayer, though you are unworthy.",
1558  godname);
1559  } else {
1560  prayer_failure(op, op->stats.grace, SP_level_spellpoint_cost(caster, spell_ob, SPELL_GRACE)-op->stats.grace);
1563  "%s ignores your prayer.",
1564  godname);
1565  return 0;
1566  }
1567  }
1568 
1569  /* player/monster is trying to cast the spell. might fumble it */
1570  if (spell_ob->stats.grace
1571  && random_roll(0, 99, op, PREFER_HIGH) < (get_cleric_chance(op->stats.Wis) * spell_ob->level/MAX(1, op->level))) {
1572  play_sound_player_only(op->contr, SOUND_TYPE_SPELL, spell_ob, 0, "fumble");
1574  "You fumble the spell.");
1575  if (settings.casting_time == TRUE) {
1576  op->casting_time = -1;
1577  }
1578  op->stats.grace -= random_roll(1, SP_level_spellpoint_cost(caster, spell_ob, SPELL_GRACE), op, PREFER_LOW);
1579  object *bungle = create_archetype(ARCH_SPELL_BUNGLE);
1580  if (bungle->arch != NULL) {
1581  cast_create_obj(op, bungle, 0);
1582  } else {
1583  LOG(llevError, "cast_spell: Could not create spell_bungle arch\n");
1584  }
1585  return 0;
1586  } else if (spell_ob->stats.sp) {
1587  int failure = random_roll(0, 199, op, PREFER_HIGH)-op->contr->encumbrance+op->level-spell_ob->level+35;
1588 
1589  if (failure < 0) {
1592  "You bungle the spell because you have too much heavy equipment in use.");
1594  spell_failure(op, failure, SP_level_spellpoint_cost(caster, spell_ob, SPELL_MANA), skill);
1595  op->contr->shoottype = old_shoottype;
1596  op->stats.sp -= random_roll(0, SP_level_spellpoint_cost(caster, spell_ob, SPELL_MANA), op, PREFER_LOW);
1597  object *bungle = create_archetype(ARCH_SPELL_BUNGLE);
1598  if (bungle->arch != NULL) {
1599  cast_create_obj(op, bungle, 0);
1600  } else {
1601  LOG(llevError, "cast_spell: Could not create spell_bungle arch\n");
1602  }
1603  return 0;
1604  }
1605  }
1606 
1607  /* ensure the potentially required items are eaten */
1608  if (!spell_consume_items(op, spell_ob))
1609  /* already warned by the function */
1610  return 0;
1611  }
1612  }
1613 
1614  if (caster == op && caster->type ==PLAYER && settings.casting_time == TRUE && spell_ob->type == SPELL) {
1615  if (op->casting_time == -1) { /* begin the casting */
1616  op->casting_time = spell_ob->casting_time*PATH_TIME_MULT(op, spell_ob);
1617  op->spell = spell_ob;
1618  /* put the stringarg into the object struct so that when the
1619  * spell is actually cast, it knows about the stringarg.
1620  * necessary for the invoke command spells.
1621  */
1622  if (stringarg) {
1623  op->spellarg = strdup_local(stringarg);
1624  } else
1625  op->spellarg = NULL;
1626  return 0;
1627  } else if (op->casting_time != 0) {
1628  if (op->type == PLAYER)
1630  "You are casting!");
1631  return 0;
1632  } else { /* casting_time == 0 */
1633  op->casting_time = -1;
1634  spell_ob = op->spell;
1635  stringarg = op->spellarg;
1636  }
1637  } else {
1638  if (!QUERY_FLAG(caster, FLAG_WIZ)) {
1639  /* Take into account how long it takes to cast the spell.
1640  * if the player is casting it, then we use the time in
1641  * the spell object. If it is a spell object, have it
1642  * take two ticks. Things that cast spells on the players
1643  * behalf (eg, altars, and whatever else) shouldn't cost
1644  * the player any time.
1645  * Ignore casting time for firewalls
1646  */
1647  if (caster == op && caster->type != FIREWALL) {
1648  op->speed_left -= spell_ob->casting_time*PATH_TIME_MULT(op, spell_ob)*FABS(op->speed);
1649  /* Other portions of the code may also decrement the speed of the player, so
1650  * put a lower limit so that the player isn't stuck here too long
1651  */
1652  if ((spell_ob->casting_time > 0)
1653  && op->speed_left < -spell_ob->casting_time*PATH_TIME_MULT(op, spell_ob)*FABS(op->speed))
1654  op->speed_left = -spell_ob->casting_time*PATH_TIME_MULT(op, spell_ob)*FABS(op->speed);
1655  } else if (caster->type == WAND
1656  || caster->type == ROD
1657  || caster->type == POTION
1658  || caster->type == SCROLL) {
1659  op->speed_left -= 2*FABS(op->speed);
1660  }
1661  }
1662  }
1663 
1664  /* We want to try to find the skill to properly credit exp.
1665  * for spell casting objects, the exp goes to the skill the casting
1666  * object requires.
1667  */
1668  if (op != caster && !skill && caster->skill && !QUERY_FLAG(op, FLAG_MONSTER)) {
1669  skill = find_skill_by_name(op, caster->skill);
1670  if (!skill) {
1671  char name[MAX_BUF];
1672 
1673  query_name(caster, name, MAX_BUF);
1676  "You lack the skill %s to use the %s",
1677  caster->skill, name);
1678  return 0;
1679  }
1680  change_skill(op, skill, 0); /* needed for proper exp credit */
1681  }
1682 
1683  /* Need to get proper ownership for spells cast via runes - these are not
1684  * the normal 'rune of fire', but rather the magic runes that let the player
1685  * put some other spell into the rune (glyph, firetrap, magic rune, etc)
1686  */
1687  if (caster->type == RUNE) {
1688  object *owner = object_get_owner(caster);
1689 
1690  if (owner)
1691  skill = find_skill_by_name(owner, caster->skill);
1692  }
1693 
1694  if (confusion_effect) {
1695  /* If we get here, the confusion effect was 'random effect', so do it and bail out. */
1698  "In your confused state, you can't control the magic!");
1700 
1701  /* Still subtract full grace and sp. */
1702  if (op->type == PLAYER && op == caster && !QUERY_FLAG(caster, FLAG_WIZ)) {
1703  op->stats.grace -= SP_level_spellpoint_cost(caster, spell_ob, SPELL_GRACE);
1704  op->stats.sp -= SP_level_spellpoint_cost(caster, spell_ob, SPELL_MANA);
1705  }
1706 
1707  return 0;
1708  }
1709 
1710  play_sound_map(SOUND_TYPE_SPELL, caster, dir, spell_ob->name);
1711 
1712  switch (spell_ob->subtype) {
1713  /* The order of case statements is same as the order they show up
1714  * in in spells.h.
1715  */
1716  case SP_RAISE_DEAD:
1717  success = cast_raise_dead_spell(op, caster, spell_ob, dir, stringarg);
1718  break;
1719 
1720  case SP_RUNE:
1721  success = write_rune(op, caster, spell_ob, dir, stringarg);
1722  break;
1723 
1724  case SP_MAKE_MARK:
1725  success = write_mark(op, spell_ob, stringarg);
1726  break;
1727 
1728  case SP_BOLT:
1729  success = fire_bolt(op, caster, dir, spell_ob);
1730  break;
1731 
1732  case SP_BULLET:
1733  success = fire_arch_from_position(op, caster, op->x+freearr_x[dir], op->y+freearr_y[dir], dir, spell_ob);
1734  break;
1735 
1736  case SP_CONE:
1737  success = cast_cone(op, caster, dir, spell_ob);
1738  break;
1739 
1740  case SP_BOMB:
1741  success = create_bomb(op, caster, dir, spell_ob);
1742  break;
1743 
1744  case SP_WONDER:
1745  success = cast_wonder(op, caster, dir, spell_ob);
1746  break;
1747 
1748  case SP_SMITE:
1749  success = cast_smite_spell(op, caster, dir, spell_ob);
1750  break;
1751 
1752  case SP_MAGIC_MISSILE:
1753  success = fire_arch_from_position(op, caster, op->x, op->y, dir, spell_ob);
1754  break;
1755 
1756  case SP_SUMMON_GOLEM:
1757  success = pets_summon_golem(op, caster, dir, spell_ob);
1758  if (success || op->contr == NULL)
1759  old_shoottype = range_golem;
1760  else
1761  /*
1762  * if the spell failed (something in the way for instance),
1763  * don't change the range so the player can try easily after that
1764  */
1765  old_shoottype = op->contr->shoottype;
1766  break;
1767 
1768  case SP_DIMENSION_DOOR:
1769  /* dimension door needs the actual caster, because that is what is
1770  * moved.
1771  */
1772  success = dimension_door(op, caster, spell_ob, dir);
1773  break;
1774 
1775  case SP_MAGIC_MAPPING:
1776  if (op->type == PLAYER) {
1777  spell_effect(spell_ob, op->x, op->y, op->map, op);
1778  draw_magic_map(op);
1779  success = 1;
1780  } else
1781  success = 0;
1782  break;
1783 
1784  case SP_MAGIC_WALL:
1785  success = magic_wall(op, caster, dir, spell_ob);
1786  break;
1787 
1788  case SP_DESTRUCTION:
1789  success = cast_destruction(op, caster, spell_ob);
1790  break;
1791 
1792  case SP_PERCEIVE_SELF:
1793  success = perceive_self(op);
1794  break;
1795 
1796  case SP_WORD_OF_RECALL:
1797  success = cast_word_of_recall(op, caster, spell_ob);
1798  break;
1799 
1800  case SP_INVISIBLE:
1801  success = cast_invisible(op, caster, spell_ob);
1802  break;
1803 
1804  case SP_PROBE:
1805  if (op != caster)
1806  cast_level = caster->level;
1807  else
1808  cast_level = skill != NULL ? skill->level : op->level;
1809  success = probe(op, caster, spell_ob, dir, cast_level);
1810  break;
1811 
1812  case SP_HEALING:
1813  success = cast_heal(op, caster, spell_ob, dir);
1814  break;
1815 
1816  case SP_CREATE_FOOD:
1817  success = cast_create_food(op, caster, spell_ob, dir, stringarg);
1818  break;
1819 
1820  case SP_EARTH_TO_DUST:
1821  success = cast_earth_to_dust(op, caster, spell_ob);
1822  break;
1823 
1824  case SP_CHANGE_ABILITY:
1825  success = cast_change_ability(op, caster, spell_ob, dir, 0);
1826  break;
1827 
1828  case SP_BLESS:
1829  success = cast_bless(op, caster, spell_ob, dir);
1830  break;
1831 
1832  case SP_CURSE:
1833  success = cast_curse(op, caster, spell_ob, dir);
1834  break;
1835 
1836  case SP_SUMMON_MONSTER:
1837  success = pets_summon_object(op, caster, spell_ob, dir, stringarg);
1838  if (!success) {
1839  cost_multiplier = 0.0f;
1840  }
1841  break;
1842 
1843  case SP_CHARGING:
1844  success = recharge(op, caster, spell_ob);
1845  break;
1846 
1847  case SP_POLYMORPH:
1848 #if 0
1849  /* Not great, but at least provide feedback so if players do have
1850  * polymorph (ie, find it as a preset item or left over from before
1851  * it was disabled), they get some feedback.
1852  */
1854  "The spell fizzles");
1855  success = 0;
1856 #else
1857  success = cast_polymorph(op, caster, spell_ob, dir);
1858 #endif
1859  break;
1860 
1861  case SP_ALCHEMY:
1862  success = alchemy(op, caster, spell_ob);
1863  break;
1864 
1865  case SP_REMOVE_CURSE:
1866  success = remove_curse(op, caster, spell_ob);
1867  break;
1868 
1869  case SP_IDENTIFY:
1870  success = cast_identify(op, caster, spell_ob);
1871  break;
1872 
1873  case SP_DETECTION:
1874  success = cast_detection(op, caster, spell_ob);
1875  break;
1876 
1877  case SP_MOOD_CHANGE:
1878  success = mood_change(op, caster, spell_ob);
1879  break;
1880 
1881  case SP_MOVING_BALL:
1882  if (spell_ob->path_repelled
1883  && (spell_ob->path_repelled&caster->path_attuned) != spell_ob->path_repelled) {
1885  "You lack the proper attunement to cast %s",
1886  spell_ob->name);
1887  success = 0;
1888  } else
1889  success = fire_arch_from_position(op, caster, op->x, op->y, dir, spell_ob);
1890  break;
1891 
1892  case SP_SWARM:
1893  success = fire_swarm(op, caster, spell_ob, dir);
1894  break;
1895 
1896  case SP_CHANGE_MANA:
1897  success = cast_transfer(op, caster, spell_ob, dir);
1898  break;
1899 
1900  case SP_DISPEL_RUNE:
1901  /* in rune.c */
1902  success = dispel_rune(op, skill, dir);
1903  break;
1904 
1905  case SP_CREATE_MISSILE:
1906  success = cast_create_missile(op, caster, spell_ob, dir, stringarg);
1907  break;
1908 
1909  case SP_CONSECRATE:
1910  success = cast_consecrate(op, caster, spell_ob);
1911  break;
1912 
1913  case SP_ANIMATE_WEAPON:
1914  success = animate_weapon(op, caster, spell_ob, dir);
1915  old_shoottype = range_golem;
1916  break;
1917 
1918  case SP_LIGHT:
1919  success = cast_light(op, caster, spell_ob, dir);
1920  break;
1921 
1922  case SP_CHANGE_MAP_LIGHT:
1923  success = cast_change_map_lightlevel(op, spell_ob);
1924  break;
1925 
1926  case SP_FAERY_FIRE:
1927  success = cast_destruction(op, caster, spell_ob);
1928  break;
1929 
1930  case SP_CAUSE_DISEASE:
1931  success = cast_cause_disease(op, caster, spell_ob, dir);
1932  break;
1933 
1934  case SP_AURA:
1935  success = create_aura(op, caster, spell_ob);
1936  break;
1937 
1938  case SP_TOWN_PORTAL:
1939  success = cast_create_town_portal(op, caster, spell_ob);
1940  break;
1941 
1942  case SP_ITEM_CURSE_BLESS:
1943  success = cast_item_curse_or_bless(op, spell_ob);
1944  break;
1945 
1946  case SP_ELEM_SHIELD:
1947  success = create_aura(op, caster, spell_ob);
1948  break;
1949 
1950  default:
1951  LOG(llevError, "cast_spell: Unhandled spell subtype %d\n", spell_ob->subtype);
1952  }
1953 
1954  /* Subtract grace and sp. */
1955  if (op->type == PLAYER && op == caster && !QUERY_FLAG(caster, FLAG_WIZ)) {
1956  op->stats.grace -= (int)(0.5 + cost_multiplier * SP_level_spellpoint_cost(caster, spell_ob, SPELL_GRACE));
1957  op->stats.sp -= (int)(0.5 + cost_multiplier * SP_level_spellpoint_cost(caster, spell_ob, SPELL_MANA));
1958  }
1959 
1960  /* FIXME - we need some better sound suppport */
1961  /* free the spell arg */
1962  if (settings.casting_time == TRUE) {
1963  free(stringarg);
1964  }
1965  /* perhaps a bit of a hack, but if using a wand, it has to change the skill
1966  * to something like use_magic_item, but you really want to be able to fire
1967  * it again.
1968  */
1969  if (op->contr)
1970  op->contr->shoottype = old_shoottype;
1971 
1972  return success;
1973 }
1974 
1981 void store_spell_expiry(object *spell) {
1982  /* Keep when to warn the player of expiration */
1983  char dur[10];
1984  int i = spell->duration/5;
1985 
1986  if (!i)
1987  i = 1;
1988  snprintf(dur, sizeof(dur), "%d", i);
1989  object_set_value(spell, "spell_expiry_warn_1", dur, 1);
1990  i = i/5;
1991  if (i > 0) {
1992  snprintf(dur, sizeof(dur), "%d", i);
1993  object_set_value(spell, "spell_expiry_warn_2", dur, 1);
1994  }
1995 }
1996 
2006 void check_spell_expiry(object *spell) {
2007  const char *key;
2008 
2009  if (!spell->env || !IS_PLAYER(spell->env))
2010  return;
2011 
2012  key = object_get_value(spell, "spell_expiry_warn_1");
2013  if (key != NULL) {
2014  if (spell->duration == atoi(key)) {
2016  "The effects of your %s are draining out.", spell->name);
2017  return;
2018  }
2019  }
2020  key = object_get_value(spell, "spell_expiry_warn_2");
2021  if (key != NULL) {
2022  if (spell->duration == atoi(key)) {
2024  "The effects of your %s are about to expire.", spell->name);
2025  return;
2026  }
2027  }
2028 }
2029 
2037 void rod_adjust(object *rod) {
2038  /*
2039  * Add 50 to both level an divisor to keep prices a little
2040  * more reasonable. Otherwise, a high level version of a
2041  * low level spell can be worth tons a money (eg, level 20
2042  * rod, level 2 spell = 10 time multiplier). This way, the
2043  * value are a bit more reasonable.
2044  */
2045  rod->value = rod->value*rod->inv->value*(rod->level+50)/(rod->inv->level+50);
2046 
2047  /*
2048  * Maxhp is used to denote how many 'charges' the rod holds
2049  * before.
2050  */
2051  rod->stats.maxhp = MAX(rod->stats.maxhp, 2)*SP_level_spellpoint_cost(rod, rod->inv, SPELL_HIGHEST);
2052  rod->stats.hp = rod->stats.maxhp;
2053 }
paralyze_living
void paralyze_living(object *op, int dam)
Definition: attack.cpp:2397
swap_random_stats
static void swap_random_stats(object *op)
Definition: spell_util.cpp:1254
GET_MAP_OB
#define GET_MAP_OB(M, X, Y)
Definition: map.h:171
PLAYER
@ PLAYER
Definition: object.h:112
object_get_owner
object * object_get_owner(object *op)
Definition: object.cpp:804
find_target_for_friendly_spell
object * find_target_for_friendly_spell(object *op, int dir)
Definition: spell_util.cpp:813
SP_MAGIC_MISSILE
#define SP_MAGIC_MISSILE
Definition: spells.h:85
global.h
SP_HEALING
#define SP_HEALING
Definition: spells.h:95
SP_BOLT
#define SP_BOLT
Definition: spells.h:78
drain_wand_charge
void drain_wand_charge(object *wand)
Definition: spell_util.cpp:786
settings
struct Settings settings
Definition: init.cpp:139
object::range_modifier
uint8_t range_modifier
Definition: object.h:416
fire_bolt
int fire_bolt(object *op, object *caster, int dir, object *spob)
Definition: spell_attack.cpp:61
object_update_turn_face
void object_update_turn_face(object *op)
Definition: object.cpp:1327
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Definition: define.h:730
living::maxhp
int16_t maxhp
Definition: living.h:41
AT_MAGIC
#define AT_MAGIC
Definition: attack.h:77
FLAG_CONFUSED
#define FLAG_CONFUSED
Definition: define.h:311
BOW
@ BOW
Definition: object.h:123
find_applied_skill_by_name
object * find_applied_skill_by_name(const object *op, const char *name)
Definition: living.cpp:1921
statistics
struct Statistics statistics
Definition: init.cpp:232
llevError
@ llevError
Definition: logger.h:11
FABS
#define FABS(x)
Definition: define.h:22
SP_BOMB
#define SP_BOMB
Definition: spells.h:82
object::path_attuned
uint32_t path_attuned
Definition: object.h:353
WAND
@ WAND
Definition: object.h:225
cast_consecrate
int cast_consecrate(object *op, object *caster, object *spell)
Definition: spell_effect.cpp:2985
drain_rod_charge
void drain_rod_charge(object *rod)
Definition: spell_util.cpp:776
cast_create_food
int cast_create_food(object *op, object *caster, object *spell_ob, int dir, const char *stringarg)
Definition: spell_effect.cpp:627
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:51
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
archetype::more
archetype * more
Definition: object.h:477
FLAG_GENERATOR
#define FLAG_GENERATOR
Definition: define.h:248
strdup_local
#define strdup_local
Definition: compat.h:29
object::inv
object * inv
Definition: object.h:298
SP_ANIMATE_WEAPON
#define SP_ANIMATE_WEAPON
Definition: spells.h:115
diamondslots.x
x
Definition: diamondslots.py:15
FLAG_STARTEQUIP
#define FLAG_STARTEQUIP
Definition: define.h:268
n
based on the size of the this randomly makes land number of spaces randomly lower or higher The default is Note that this is run also based on the the altitude amount will likely be less So if you do something like l and n
Definition: land.6.txt:25
SP_FAERY_FIRE
#define SP_FAERY_FIRE
Definition: spells.h:118
shuffle_attack
void shuffle_attack(object *op)
Definition: spell_util.cpp:1033
MSG_TYPE_SKILL
#define MSG_TYPE_SKILL
Definition: newclient.h:396
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
ARCH_SPELL_BUNGLE
#define ARCH_SPELL_BUNGLE
Definition: object.h:585
cast_identify
int cast_identify(object *op, object *caster, object *spell)
Definition: spell_effect.cpp:2503
dimension_door
int dimension_door(object *op, object *caster, object *spob, int dir)
Definition: spell_effect.cpp:1609
cast_change_map_lightlevel
int cast_change_map_lightlevel(object *op, object *spell)
Definition: spell_effect.cpp:3293
perceive_self
int perceive_self(object *op)
Definition: spell_effect.cpp:1002
get_cleric_chance
int get_cleric_chance(int stat)
Definition: living.cpp:2370
confuse_living
void confuse_living(object *op, object *hitter, int dam)
Definition: attack.cpp:2310
cast_destruction
int cast_destruction(object *op, object *caster, object *spell_ob)
Definition: spell_attack.cpp:707
op_on_battleground
int op_on_battleground(object *op, int *x, int *y, archetype **trophy)
Definition: player.cpp:4249
FALSE
#define FALSE
Definition: compat.h:14
object::arch
struct archetype * arch
Definition: object.h:422
absdir
int absdir(int d)
Definition: object.cpp:3705
tailor_god_spell
int tailor_god_spell(object *spellop, object *caster)
Definition: gods.cpp:1222
object::speed
float speed
Definition: object.h:337
caster_level
int caster_level(const object *caster, const object *spell)
Definition: spell_util.cpp:194
object::x
int16_t x
Definition: object.h:335
OB_SPELL_TAG_MATCH
#define OB_SPELL_TAG_MATCH(op, count)
Definition: object.h:95
magic_wall
int magic_wall(object *op, object *caster, int dir, object *spell_ob)
Definition: spell_effect.cpp:1456
check_bullet
void check_bullet(object *op)
Definition: spell_attack.cpp:217
spell_failure
void spell_failure(object *op, int failure, int power, object *skill)
Definition: spell_util.cpp:1103
can_be_transmuted_to_flower
static int can_be_transmuted_to_flower(object *op)
Definition: spell_util.cpp:1161
PREFER_LOW
#define PREFER_LOW
Definition: define.h:564
object::anim_suffix
sstring anim_suffix
Definition: object.h:324
WEAPON
@ WEAPON
Definition: object.h:124
cast_cause_disease
int cast_cause_disease(object *op, object *caster, object *spell, int dir)
Definition: spell_attack.cpp:1207
object_find_first_free_spot
int object_find_first_free_spot(const object *ob, mapstruct *m, int x, int y)
Definition: object.cpp:3590
SP_CONSECRATE
#define SP_CONSECRATE
Definition: spells.h:114
LOOSE_MANA
#define LOOSE_MANA
Definition: spells.h:162
object_set_owner
void object_set_owner(object *op, object *owner)
Definition: object.cpp:840
guildjoin.ob
ob
Definition: guildjoin.py:42
MSG_TYPE_ATTRIBUTE
#define MSG_TYPE_ATTRIBUTE
Definition: newclient.h:394
range_none
@ range_none
Definition: player.h:30
SP_CONE
#define SP_CONE
Definition: spells.h:81
commongive.inv
inv
Definition: commongive.py:29
SET_ANIMATION
#define SET_ANIMATION(ob, newanim)
Definition: global.h:162
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
SP_CAUSE_DISEASE
#define SP_CAUSE_DISEASE
Definition: spells.h:119
Settings::spell_failure_effects
uint8_t spell_failure_effects
Definition: global.h:269
play_sound_player_only
void play_sound_player_only(player *pl, int8_t sound_type, object *emitter, int dir, const char *action)
Definition: sounds.cpp:51
MSG_TYPE_VICTIM_SPELL
#define MSG_TYPE_VICTIM_SPELL
Definition: newclient.h:643
cast_curse
int cast_curse(object *op, object *caster, object *spell_ob, int dir)
Definition: spell_attack.cpp:800
play_sound_map
void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action)
Definition: sounds.cpp:113
flags
static const flag_definition flags[]
Definition: gridarta-types-convert.cpp:101
Ice.tmp
int tmp
Definition: Ice.py:207
FLAG_WIZCAST
#define FLAG_WIZCAST
Definition: define.h:289
RUNE
@ RUNE
Definition: object.h:245
change_skill
int change_skill(object *who, object *new_skill, int flag)
Definition: skill_util.cpp:359
SP_CREATE_FOOD
#define SP_CREATE_FOOD
Definition: spells.h:96
fix_object
void fix_object(object *op)
Definition: living.cpp:1125
cast_raise_dead_spell
int cast_raise_dead_spell(object *op, object *caster, object *spell, int dir, const char *arg)
Definition: resurrection.cpp:181
DIRX
#define DIRX(xyz)
Definition: define.h:463
AT_INTERNAL
#define AT_INTERNAL
Definition: attack.h:99
write_mark
int write_mark(object *op, object *spell, const char *msg)
Definition: spell_effect.cpp:3411
NDI_NAVY
#define NDI_NAVY
Definition: newclient.h:233
SP_level_wc_adjust
int SP_level_wc_adjust(const object *caster, const object *spob)
Definition: spell_util.cpp:362
cast_polymorph
int cast_polymorph(object *op, object *caster, object *spell_ob, int dir)
Definition: spell_effect.cpp:425
P_NO_MAGIC
#define P_NO_MAGIC
Definition: map.h:226
TRANSPORT
@ TRANSPORT
Definition: object.h:113
lookup_spell_by_name
object * lookup_spell_by_name(object *op, const char *spname)
Definition: spell_util.cpp:410
set_spell_skill
void set_spell_skill(object *op, object *caster, object *spob, object *dest)
Definition: spell_util.cpp:94
SP_CREATE_MISSILE
#define SP_CREATE_MISSILE
Definition: spells.h:113
SP_DISPEL_RUNE
#define SP_DISPEL_RUNE
Definition: spells.h:112
handle_spell_confusion
static void handle_spell_confusion(object *op)
Definition: spell_util.cpp:1289
range_golem
@ range_golem
Definition: player.h:34
apply_manual
int apply_manual(object *op, object *tmp, int aflag)
Definition: apply.cpp:597
MSG_TYPE_SPELL_INFO
#define MSG_TYPE_SPELL_INFO
Definition: newclient.h:628
object_get_value
const char * object_get_value(const object *op, const char *const key)
Definition: object.cpp:4337
AssetsManager.h
create_treasure
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.cpp:263
FLAG_APPLIED
#define FLAG_APPLIED
Definition: define.h:235
object::level
int16_t level
Definition: object.h:361
summon_hostile_monsters
int summon_hostile_monsters(object *op, int n, const char *monstername)
Definition: spell_util.cpp:1005
Chaos_Attacks::attacktype
int attacktype
Definition: attack.h:126
getManager
AssetsManager * getManager()
Definition: assets.cpp:305
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.cpp:2848
HUGE_BUF
#define HUGE_BUF
Definition: define.h:37
MSG_TYPE_VICTIM
#define MSG_TYPE_VICTIM
Definition: newclient.h:404
cast_spell
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Definition: spell_util.cpp:1424
MAX
#define MAX(x, y)
Definition: compat.h:24
min_casting_level
int min_casting_level(const object *caster, const object *spell)
Definition: spell_util.cpp:164
cast_detection
int cast_detection(object *op, object *caster, object *spell)
Definition: spell_effect.cpp:2578
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
cast_magic_storm
void cast_magic_storm(object *op, object *tmp, int lvl)
Definition: spell_effect.cpp:49
pets_summon_object
int pets_summon_object(object *op, object *caster, object *spell_ob, int dir, const char *stringarg)
Definition: pets.cpp:872
reflwall
int reflwall(mapstruct *m, int x, int y, object *sp_op)
Definition: spell_util.cpp:470
cast_light
int cast_light(object *op, object *caster, object *spell, int dir)
Definition: spell_attack.cpp:1136
draw_ext_info
vs only yadda is in because all tags get reset on the next draw_ext_info In the second since it is all in one draw_ext_info
Definition: media-tags.txt:61
FLAG_ALIVE
#define FLAG_ALIVE
Definition: define.h:230
object::path_denied
uint32_t path_denied
Definition: object.h:355
esrv_send_item
void esrv_send_item(object *pl, object *op)
Definition: main.cpp:354
SP_SUMMON_MONSTER
#define SP_SUMMON_MONSTER
Definition: spells.h:101
object::y
int16_t y
Definition: object.h:335
object::path_repelled
uint32_t path_repelled
Definition: object.h:354
m
static event_registration m
Definition: citylife.cpp:425
PATH_SP_MULT
#define PATH_SP_MULT(op, spell)
Definition: spells.h:36
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.cpp:1555
PREFER_HIGH
#define PREFER_HIGH
Definition: define.h:563
cast_heal
int cast_heal(object *op, object *caster, object *spell, int dir)
Definition: spell_effect.cpp:1745
SP_BULLET
#define SP_BULLET
Definition: spells.h:79
disinfect.map
map
Definition: disinfect.py:4
SP_ITEM_CURSE_BLESS
#define SP_ITEM_CURSE_BLESS
Definition: spells.h:123
SP_TOWN_PORTAL
#define SP_TOWN_PORTAL
Definition: spells.h:121
object::subtype
uint8_t subtype
Definition: object.h:349
add_refcount
sstring add_refcount(sstring str)
Definition: shstr.cpp:210
determine_god
const char * determine_god(object *op)
Definition: gods.cpp:55
freearr_y
short freearr_y[SIZEOFFREE]
Definition: object.cpp:305
remove_curse
int remove_curse(object *op, object *caster, object *spell)
Definition: spell_effect.cpp:2404
mood_change
int mood_change(object *op, object *caster, object *spell)
Definition: spell_attack.cpp:904
SP_MOOD_CHANGE
#define SP_MOOD_CHANGE
Definition: spells.h:108
SPELL_WONDER
#define SPELL_WONDER
Definition: spells.h:163
query_name
void query_name(const object *op, char *buf, size_t size)
Definition: item.cpp:592
MSG_TYPE_ATTRIBUTE_PROTECTION_GAIN
#define MSG_TYPE_ATTRIBUTE_PROTECTION_GAIN
Definition: newclient.h:544
POTION
@ POTION
Definition: object.h:116
can_see_monsterP
int can_see_monsterP(mapstruct *m, int x, int y, int dir)
Definition: object.cpp:3813
GT_INVISIBLE
@ GT_INVISIBLE
Definition: treasure.h:32
ok_to_put_more
int ok_to_put_more(mapstruct *m, int16_t x, int16_t y, object *op, uint32_t immune_stop)
Definition: spell_util.cpp:530
SP_DIMENSION_DOOR
#define SP_DIMENSION_DOOR
Definition: spells.h:87
archetype::clone
object clone
Definition: object.h:478
apply_anim_suffix
void apply_anim_suffix(object *who, const char *suffix)
Definition: anim.cpp:150
isqrt
int isqrt(int n)
Definition: utils.cpp:559
HEAD
#define HEAD(op)
Definition: object.h:598
range_magic
@ range_magic
Definition: player.h:32
ROD
@ ROD
Definition: object.h:114
SP_level_duration_adjust
int SP_level_duration_adjust(const object *caster, const object *spob)
Definition: spell_util.cpp:312
SP_level_spellpoint_cost
int16_t SP_level_spellpoint_cost(object *caster, object *spell, int flags)
Definition: spell_util.cpp:236
create_bomb
int create_bomb(object *op, object *caster, int dir, object *spell)
Definition: spell_attack.cpp:447
object::casting_time
int16_t casting_time
Definition: object.h:412
object_find_by_type_and_name
object * object_find_by_type_and_name(const object *who, int type, const char *name)
Definition: object.cpp:4099
query_short_name
void query_short_name(const object *op, char *buf, size_t size)
Definition: item.cpp:517
set_attr_value
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.cpp:218
rod_adjust
void rod_adjust(object *rod)
Definition: spell_util.cpp:2037
SPELL_GRACE
#define SPELL_GRACE
Definition: spells.h:59
MSG_TYPE_ITEM
#define MSG_TYPE_ITEM
Definition: newclient.h:401
object::face
const Face * face
Definition: object.h:341
AP_IGNORE_CURSE
#define AP_IGNORE_CURSE
Definition: define.h:582
SP_REMOVE_CURSE
#define SP_REMOVE_CURSE
Definition: spells.h:105
object::value
int32_t value
Definition: object.h:360
object_update_speed
void object_update_speed(object *op)
Definition: object.cpp:1344
Statistics::spell_suppressions
uint64_t spell_suppressions
Definition: global.h:364
SPELL_HIGHEST
#define SPELL_HIGHEST
Definition: spells.h:60
object::type
uint8_t type
Definition: object.h:348
SP_SMITE
#define SP_SMITE
Definition: spells.h:84
FORCE_TRANSFORMED_ITEM
#define FORCE_TRANSFORMED_ITEM
Definition: spells.h:146
cast_create_town_portal
int cast_create_town_portal(object *op, object *caster, object *spell)
Definition: spell_effect.cpp:1241
draw_magic_map
void draw_magic_map(object *pl)
Definition: info.cpp:474
SP_DETECTION
#define SP_DETECTION
Definition: spells.h:107
spell
with a maximum of six This is not so if you are wearing plate you receive no benefit Armour is additive with all the supplementry forms of which means that it lasts until the next semi permanent spell effect is cast upon the character spell
Definition: tome-of-magic.txt:44
store_spell_expiry
void store_spell_expiry(object *spell)
Definition: spell_util.cpp:1981
GET_MAP_MOVE_BLOCK
#define GET_MAP_MOVE_BLOCK(M, X, Y)
Definition: map.h:191
FOR_INV_FINISH
#define FOR_INV_FINISH()
Definition: define.h:677
AssetsManager::archetypes
Archetypes * archetypes()
Definition: AssetsManager.h:44
create_aura
int create_aura(object *op, object *caster, object *spell)
Definition: spell_effect.cpp:3325
INS_BELOW_ORIGINATOR
#define INS_BELOW_ORIGINATOR
Definition: object.h:575
living::food
int32_t food
Definition: living.h:48
GOLEM
@ GOLEM
Definition: object.h:150
MSG_TYPE_SKILL_MISSING
#define MSG_TYPE_SKILL_MISSING
Definition: newclient.h:576
disinfect.count
int count
Definition: disinfect.py:7
rangetype
rangetype
Definition: player.h:28
tag_t
uint32_t tag_t
Definition: object.h:14
archetype
Definition: object.h:474
dump_spells
void dump_spells(void)
Definition: spell_util.cpp:108
sproto.h
ARROW
@ ARROW
Definition: object.h:122
living::sp
int16_t sp
Definition: living.h:42
MSG_TYPE_SPELL
#define MSG_TYPE_SPELL
Definition: newclient.h:400
Settings::casting_time
uint8_t casting_time
Definition: global.h:270
SOUND_TYPE_SPELL
#define SOUND_TYPE_SPELL
Definition: newclient.h:323
regenerate_rod
void regenerate_rod(object *rod)
Definition: spell_util.cpp:761
SP_EARTH_TO_DUST
#define SP_EARTH_TO_DUST
Definition: spells.h:97
SP_CHANGE_MAP_LIGHT
#define SP_CHANGE_MAP_LIGHT
Definition: spells.h:117
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.cpp:2095
SP_DESTRUCTION
#define SP_DESTRUCTION
Definition: spells.h:90
ATTACKS
Chaos_Attacks ATTACKS[22]
Definition: init.cpp:81
object::other_arch
struct archetype * other_arch
Definition: object.h:423
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
fire_arch_from_position
int fire_arch_from_position(object *op, object *caster, int16_t x, int16_t y, int dir, object *spell)
Definition: spell_util.cpp:629
find_skill_by_name
object * find_skill_by_name(object *who, const char *name)
Definition: skill_util.cpp:211
SIZEOFFREE
#define SIZEOFFREE
Definition: define.h:155
P_OUT_OF_MAP
#define P_OUT_OF_MAP
Definition: map.h:248
MAX_BUF
#define MAX_BUF
Definition: define.h:35
cast_bless
int cast_bless(object *op, object *caster, object *spell_ob, int dir)
Definition: spell_effect.cpp:2048
esrv_del_item
void esrv_del_item(player *pl, object *ob)
Definition: main.cpp:381
create_archetype
object * create_archetype(const char *name)
Definition: arch.cpp:278
object::weight
int32_t weight
Definition: object.h:375
spell_find_dir
int spell_find_dir(mapstruct *m, int x, int y, object *exclude)
Definition: spell_util.cpp:887
RANDOM
#define RANDOM()
Definition: define.h:644
IS_PLAYER
static bool IS_PLAYER(object *op)
Definition: object.h:600
FREE_AND_CLEAR_STR
#define FREE_AND_CLEAR_STR(xyz)
Definition: global.h:198
SP_MAGIC_WALL
#define SP_MAGIC_WALL
Definition: spells.h:89
probe
int probe(object *op, object *caster, object *spell_ob, int dir, int level)
Definition: spell_effect.cpp:699
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:723
SP_INVISIBLE
#define SP_INVISIBLE
Definition: spells.h:93
change_abil
int change_abil(object *op, object *tmp)
Definition: living.cpp:394
spell_consume_items
static int spell_consume_items(object *op, const object *spell_ob)
Definition: spell_util.cpp:1308
OUT_OF_REAL_MAP
#define OUT_OF_REAL_MAP(M, X, Y)
Definition: map.h:216
get_search_arr
void get_search_arr(int *search_arr)
Definition: object.cpp:3633
SP_PROBE
#define SP_PROBE
Definition: spells.h:94
range_misc
@ range_misc
Definition: player.h:33
sounds.h
object_decrease_nrof
object * object_decrease_nrof(object *op, uint32_t i)
Definition: object.cpp:2667
SP_PERCEIVE_SELF
#define SP_PERCEIVE_SELF
Definition: spells.h:91
FLAG_REFL_SPELL
#define FLAG_REFL_SPELL
Definition: define.h:275
FLAG_WIZ
#define FLAG_WIZ
Definition: define.h:231
object::dam_modifier
uint8_t dam_modifier
Definition: object.h:417
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:251
spells.h
object::duration_modifier
uint8_t duration_modifier
Definition: object.h:414
object::name
sstring name
Definition: object.h:319
ob_process
method_ret ob_process(object *op)
Definition: ob_methods.cpp:67
MSG_TYPE_SKILL_FAILURE
#define MSG_TYPE_SKILL_FAILURE
Definition: newclient.h:579
alchemy
int alchemy(object *op, object *caster, object *spell_ob)
Definition: spell_effect.cpp:2304
bigchest.check
check
Definition: bigchest.py:10
animate_weapon
int animate_weapon(object *op, object *caster, object *spell, int dir)
Definition: spell_effect.cpp:3063
AssetsCollection::each
void each(std::function< void(T *)> op)
Definition: AssetsCollection.h:158
MSG_TYPE_SPELL_FAILURE
#define MSG_TYPE_SPELL_FAILURE
Definition: newclient.h:622
SP_CHANGE_ABILITY
#define SP_CHANGE_ABILITY
Definition: spells.h:98
get_map_flags
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.cpp:299
PATH_TIME_MULT
#define PATH_TIME_MULT(op, spell)
Definition: spells.h:152
item
Definition: item.py:1
FIREWALL
@ FIREWALL
Definition: object.h:173
SP_MOVING_BALL
#define SP_MOVING_BALL
Definition: spells.h:109
mapstruct
Definition: map.h:314
SP_RUNE
#define SP_RUNE
Definition: spells.h:76
sstring
const typedef char * sstring
Definition: sstring.h:2
find_random_spell_in_ob
object * find_random_spell_in_ob(object *ob, const char *skill)
Definition: spell_util.cpp:48
give.op
op
Definition: give.py:33
ARCH_SPELL_BLOCKED
#define ARCH_SPELL_BLOCKED
Definition: object.h:584
object::skill
sstring skill
Definition: object.h:329
SP_level_range_adjust
int SP_level_range_adjust(const object *caster, const object *spob)
Definition: spell_util.cpp:338
MSG_TYPE_SPELL_ERROR
#define MSG_TYPE_SPELL_ERROR
Definition: newclient.h:625
spell_effect
void spell_effect(object *spob, int x, int y, mapstruct *map, object *originator)
Definition: spell_util.cpp:144
GOD_POWER
#define GOD_POWER
Definition: spells.h:164
convert.dest
dest
Definition: convert.py:25
SP_POLYMORPH
#define SP_POLYMORPH
Definition: spells.h:103
cast_create_obj
int cast_create_obj(object *op, object *new_op, int dir)
Definition: spell_util.cpp:494
pets_summon_golem
int pets_summon_golem(object *op, object *caster, int dir, object *spob)
Definition: pets.cpp:651
Settings::spellpoint_level_depend
uint8_t spellpoint_level_depend
Definition: global.h:274
esrv_update_item
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.cpp:359
FLAG_REFLECTING
#define FLAG_REFLECTING
Definition: define.h:262
dispel_rune
int dispel_rune(object *op, object *skill, int dir)
Definition: rune.cpp:295
hit_player
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
Definition: attack.cpp:1902
diamondslots.y
y
Definition: diamondslots.py:16
assets.h
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
random_roll
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.cpp:42
AP_NOPRINT
#define AP_NOPRINT
Definition: define.h:585
cast_wonder
int cast_wonder(object *op, object *caster, int dir, object *spell_ob)
Definition: spell_effect.cpp:968
SP_MAGIC_MAPPING
#define SP_MAGIC_MAPPING
Definition: spells.h:88
SP_CHARGING
#define SP_CHARGING
Definition: spells.h:102
SP_CHANGE_MANA
#define SP_CHANGE_MANA
Definition: spells.h:111
arch_to_object
object * arch_to_object(archetype *at)
Definition: arch.cpp:229
level
int level
Definition: readable.cpp:1550
split_string
size_t split_string(char *str, char *array[], size_t array_size, char sep)
Definition: utils.cpp:473
castle_read.key
key
Definition: castle_read.py:64
make_face_from_files.int
int
Definition: make_face_from_files.py:32
FLAG_ANIMATE
#define FLAG_ANIMATE
Definition: define.h:242
SP_level_dam_adjust
int SP_level_dam_adjust(const object *caster, const object *spob)
Definition: spell_util.cpp:287
AT_COUNTERSPELL
#define AT_COUNTERSPELL
Definition: attack.h:95
object::randomitems
struct treasurelist * randomitems
Definition: object.h:395
prayer_failure
static void prayer_failure(object *op, int failure, int power)
Definition: spell_util.cpp:1052
SP_BLESS
#define SP_BLESS
Definition: spells.h:99
check_spell_known
object * check_spell_known(object *op, const char *name)
Definition: spell_util.cpp:394
AT_GODPOWER
#define AT_GODPOWER
Definition: attack.h:96
fire_swarm
int fire_swarm(object *op, object *caster, object *spell, int dir)
Definition: spell_attack.cpp:1088
skill
skill
Definition: arch-handbook.txt:585
put_a_monster
static int put_a_monster(object *op, const char *monstername)
Definition: spell_util.cpp:939
first
Crossfire Protocol most of the time after the actual code was already omit certain important and possibly make life miserable any new developer or curious player should be able to find most of the relevant information here If inconsistencies are found or this documentation proves to be consider the latest server side protocol code in the public source code repository as the authoritative reference Introduction If you were ever curious enough to telnet or netcat to a Crossfire chances are you were sorely disappointed While the protocol may seem to use plain text at first
Definition: protocol.txt:20
object_remove
void object_remove(object *op)
Definition: object.cpp:1828
try_find_archetype
archetype * try_find_archetype(const char *name)
Definition: assets.cpp:270
SP_RAISE_DEAD
#define SP_RAISE_DEAD
Definition: spells.h:75
cast_change_ability
int cast_change_ability(object *op, object *caster, object *spell_ob, int dir, int silent)
Definition: spell_effect.cpp:1900
SP_MAKE_MARK
#define SP_MAKE_MARK
Definition: spells.h:77
SP_ALCHEMY
#define SP_ALCHEMY
Definition: spells.h:104
freedir
int freedir[SIZEOFFREE]
Definition: object.cpp:317
SP_SUMMON_GOLEM
#define SP_SUMMON_GOLEM
Definition: spells.h:86
OB_TYPE_MOVE_BLOCK
#define OB_TYPE_MOVE_BLOCK(ob1, type)
Definition: define.h:432
P_NO_CLERIC
#define P_NO_CLERIC
Definition: map.h:237
MSG_TYPE_ITEM_CHANGE
#define MSG_TYPE_ITEM_CHANGE
Definition: newclient.h:633
cast_word_of_recall
int cast_word_of_recall(object *op, object *caster, object *spell_ob)
Definition: spell_effect.cpp:906
UPD_ANIM
#define UPD_ANIM
Definition: newclient.h:308
SP_WONDER
#define SP_WONDER
Definition: spells.h:83
object_copy_owner
void object_copy_owner(object *op, object *clone)
Definition: object.cpp:893
SCROLL
@ SCROLL
Definition: object.h:226
write_rune
int write_rune(object *op, object *caster, object *spell, int dir, const char *runename)
Definition: rune.cpp:50
rndm
int rndm(int min, int max)
Definition: utils.cpp:162
living::grace
int16_t grace
Definition: living.h:44
say.item
dictionary item
Definition: say.py:149
object::stats
living stats
Definition: object.h:378
object_set_value
int object_set_value(object *op, const char *key, const char *value, int add_key)
Definition: object.cpp:4490
object::more
object * more
Definition: object.h:303
get_attr_value
int8_t get_attr_value(const living *stats, int attr)
Definition: living.cpp:313
AP_UNAPPLY
#define AP_UNAPPLY
Definition: define.h:575
cast_create_missile
int cast_create_missile(object *op, object *caster, object *spell, int dir, const char *stringarg)
Definition: spell_effect.cpp:493
cast_transfer
int cast_transfer(object *op, object *caster, object *spell, int dir)
Definition: spell_effect.cpp:2836
freearr_x
short freearr_x[SIZEOFFREE]
Definition: object.cpp:299
TRUE
#define TRUE
Definition: compat.h:11
AT_HOLYWORD
#define AT_HOLYWORD
Definition: attack.h:97
SPELL
@ SPELL
Definition: object.h:219
SP_IDENTIFY
#define SP_IDENTIFY
Definition: spells.h:106
cast_item_curse_or_bless
int cast_item_curse_or_bless(object *op, object *spell_ob)
Definition: spell_effect.cpp:2452
check_spell_expiry
void check_spell_expiry(object *spell)
Definition: spell_util.cpp:2006
cast_smite_spell
int cast_smite_spell(object *op, object *caster, int dir, object *spell)
Definition: spell_attack.cpp:546
SPELL_TAG_SIZE
#define SPELL_TAG_SIZE
Definition: object.h:83
SP_SWARM
#define SP_SWARM
Definition: spells.h:110
MSG_TYPE_APPLY
#define MSG_TYPE_APPLY
Definition: newclient.h:397
SP_LIGHT
#define SP_LIGHT
Definition: spells.h:116
cast_earth_to_dust
int cast_earth_to_dust(object *op, object *caster, object *spell_ob)
Definition: spell_effect.cpp:855
recharge
int recharge(object *op, object *caster, object *spell_ob)
Definition: spell_effect.cpp:84
MSG_TYPE_APPLY_ERROR
#define MSG_TYPE_APPLY_ERROR
Definition: newclient.h:590
object_get_player_container
object * object_get_player_container(object *op)
Definition: object.cpp:607
living.h
SP_CURSE
#define SP_CURSE
Definition: spells.h:100
NUM_STATS
@ NUM_STATS
Definition: living.h:18
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:670
living::hp
int16_t hp
Definition: living.h:40
object.h
cast_invisible
int cast_invisible(object *op, object *caster, object *spell_ob)
Definition: spell_effect.cpp:803
SP_WORD_OF_RECALL
#define SP_WORD_OF_RECALL
Definition: spells.h:92
DIRY
#define DIRY(xyz)
Definition: define.h:464
cast_cone
int cast_cone(object *op, object *caster, int dir, object *spell)
Definition: spell_attack.cpp:297
P_BLOCKSVIEW
#define P_BLOCKSVIEW
Definition: map.h:225
transmute_item_to_flower
static void transmute_item_to_flower(object *op)
Definition: spell_util.cpp:1183
FORCE_NAME
#define FORCE_NAME
Definition: spells.h:169
SP_ELEM_SHIELD
#define SP_ELEM_SHIELD
Definition: spells.h:124
SPELL_MANA
#define SPELL_MANA
Definition: spells.h:58
dragon_attune.force
force
Definition: dragon_attune.py:45
SP_AURA
#define SP_AURA
Definition: spells.h:120
level
Definition: level.py:1