Atrinik Server  4.0
spell_util.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
30 #include <global.h>
31 #include <spellist.h>
32 #include <toolkit/string.h>
33 #include <plugin.h>
34 #include <arch.h>
35 #include <player.h>
36 #include <object.h>
37 #include <object_methods.h>
38 
44 
48 static double spell_dam_bonus[MAX_STAT + 1] = {
49  -2.5, // 0
50  -2.0, -1.75, -1.5, -1.25, -1.0, // 1-5
51  -0.5, -0.5, -0.5, -0.25, -0.25, // 6-10
52  0.0, 0.0, 0.0, 0.0, 0.0, // 11-15
53  0.15, 0.25, 0.4, 0.5, 0.65, // 16-20
54  0.75, 0.85, 0.95, 1.10, 1.30, // 21-25
55  1.45, 1.55, 1.65, 1.80, 2.0, // 26-30
56 };
57 
61 void init_spells(void)
62 {
63  static int init_spells_done = 0;
64  int i;
65 
66  if (init_spells_done) {
67  return;
68  }
69 
70  init_spells_done = 1;
71 
72  for (i = 0; i < NROFREALSPELLS; i++) {
73  char spellname[MAX_BUF], tmpresult[MAX_BUF];
74  archetype_t *at;
75 
76  string_replace(spells[i].name, " ", "_", tmpresult, sizeof(spellname));
77  snprintf(spellname, sizeof(spellname), "spell_%s", tmpresult);
78 
79  at = arch_find(spellname);
80 
81  if (!at) {
82  LOG(ERROR, "Could not find required archetype %s.", spellname);
83  exit(1);
84  }
85 
86  spells[i].at = at;
87 
88  at->clone.stats.sp = i;
89 
90  if (at->clone.value != 0) {
91  spells[i].spell_use |= SPELL_USE_BOOK;
92  }
93 
94  if (spells[i].archname) {
95  if ((spellarch[i] = arch_find(spells[i].archname)) == NULL) {
96  LOG(ERROR, "Spell %s needs arch %s, your archetypes file is out of date.", spells[i].name, spells[i].archname);
97  exit(1);
98  }
99  } else {
100  spellarch[i] = NULL;
101  }
102  }
103 }
104 
118 int insert_spell_effect(const char *archname, mapstruct *m, int x, int y)
119 {
120  archetype_t *effect_arch;
121  object *effect_ob;
122 
123  if (!archname || !m) {
124  LOG(BUG, "archname or map NULL.");
125  return 1;
126  }
127 
128  if (!(effect_arch = arch_find(archname))) {
129  LOG(BUG, "Couldn't find effect arch (%s).", archname);
130  return 1;
131  }
132 
133  /* Prepare effect */
134  effect_ob = arch_to_object(effect_arch);
135  effect_ob->map = m;
136  effect_ob->x = x;
137  effect_ob->y = y;
138 
139  if (!object_insert_map(effect_ob, m, NULL, 0)) {
140  LOG(BUG, "effect arch (%s) out of map (%s) (%d,%d) or failed insertion.", archname, effect_ob->map->name, x, y);
141 
142  /* Something is wrong - kill object */
143  if (!QUERY_FLAG(effect_ob, FLAG_REMOVED)) {
144  object_remove(effect_ob, 0);
145  }
146 
147  return 1;
148  }
149 
150  return 0;
151 }
152 
160 spell_struct *find_spell(int spelltype)
161 {
162  if (spelltype < 0 || spelltype >= NROFREALSPELLS) {
163  return NULL;
164  }
165 
166  return &spells[spelltype];
167 }
168 
192 int cast_spell(object *op, object *caster, int dir, int type, int ability, int item, const char *stringarg)
193 {
194  spell_struct *s;
195  object *target = NULL;
196  int success = 0, duration, spell_cost = 0;
197 
198  if (op == NULL && caster != NULL) {
199  op = caster;
200  } else if (caster == NULL && op != NULL) {
201  caster = op;
202  } else if (op == NULL && caster == NULL) {
203  LOG(BUG, "Both 'op' and 'caster' are NULL.");
204  return 0;
205  }
206 
207  s = find_spell(type);
208 
209  if (s == NULL) {
210  LOG(BUG, "Unknown spell: %d", type);
211  return 0;
212  }
213 
214  /* Get the base duration */
215  duration = spells[type].bdur;
216 
217  /* Script NPCs can ALWAYS cast - even in no spell areas! */
218  if (item == CAST_NPC) {
219  /* If CAST_NPC, this usually comes from a script,
220  * and caster is the NPC and op the target. */
221  target = op;
222  op = caster;
223  } else {
224  /* It looks like the only properties we ever care about from the casting
225  * object (caster) is spell paths and level. */
226  object *cast_op = op;
227  MapSpace *msp;
228 
229  /* Caster has a map? Then we use caster */
230  if (caster->map) {
231  cast_op = caster;
232  }
233 
234  /* No magic. */
235  if (MAP_NOMAGIC(cast_op->map)) {
236  draw_info(COLOR_WHITE, op, "Powerful countermagic cancels all spellcasting here!");
237  return 0;
238  }
239 
240  msp = GET_MAP_SPACE_PTR(cast_op->map, cast_op->x, cast_op->y);
241 
242  /* No harm spell and not town safe. */
243  if ((MAP_NOHARM(cast_op->map) || (msp->extra_flags & MSP_EXTRA_NO_HARM)) && !(MAP_NOHARM(cast_op->map) && (msp->extra_flags & MSP_EXTRA_NO_HARM)) && !(spells[type].flags & SPELL_DESC_TOWN)) {
244  draw_info(COLOR_WHITE, op, "Powerful countermagic cancels all harmful magic here!");
245  return 0;
246  }
247 
248  if (op->type == PLAYER) {
249  /* Cancel player spells which are denied, but only real spells (not
250  * potions, wands, etc). */
251  if (item == CAST_NORMAL) {
252  if (caster->path_denied & s->path) {
253  draw_info(COLOR_WHITE, op, "It is denied for you to cast that spell.");
254  return 0;
255  }
256 
257  if (op->type != PLAYER || !CONTR(op)->tgm) {
258  if (op->stats.sp < SP_level_spellpoint_cost(caster, type, -1)) {
259  draw_info(COLOR_WHITE, op, "You don't have enough mana.");
260  return 0;
261  }
262  }
263  }
264  }
265 
266  if (item == CAST_POTION) {
267  /* If the potion casts a self spell, don't use the facing
268  * direction. */
269  if (spells[type].flags & SPELL_DESC_SELF) {
270  target = op;
271  dir = 0;
272  }
273  } else if (find_target_for_spell(op, &target, spells[type].flags) == 0) {
274  draw_info_format(COLOR_WHITE, op, "You can't cast that spell on %s!", target ? target->name : "yourself");
275  return 0;
276  }
277 
278  /* If valid target is not in range for selected spell, skip casting. */
279  if (target) {
280  rv_vector rv;
281 
282  if (!get_rangevector_from_mapcoords(op->map, op->x, op->y, target->map, target->x, target->y, &rv, RV_DIAGONAL_DISTANCE) || rv.distance > (unsigned int) spells[type].range) {
283  draw_info(COLOR_WHITE, op, "Your target is out of range!");
284  return 0;
285  }
286  }
287 
288  if (op->type == PLAYER && target == op && CONTR(op)->target_object != op) {
289  draw_info(COLOR_WHITE, op, "You auto-target yourself with this spell!");
290  }
291 
292  if (!ability && blocks_magic(op->map, op->x, op->y)) {
293  if (op->type != PLAYER) {
294  return 0;
295  }
296 
297  if (caster == op) {
298  draw_info(COLOR_WHITE, op, "Something blocks your spellcasting.");
299  } else {
300  char *name = object_get_name_s(caster, op);
301  draw_info_format(COLOR_WHITE, op, "Something blocks the magic "
302  "of your %s.", name);
303  efree(name);
304  }
305 
306  return 0;
307  }
308  }
309 
310  /* A last sanity check: are caster and target *really* valid? */
311  if (!OBJECT_ACTIVE(caster) || (target && !OBJECT_ACTIVE(target))) {
312  return 0;
313  }
314 
315  /* Trigger the map-wide spell event. */
316  if (op->map && op->map->events) {
317  int retval = trigger_map_event(MEVENT_SPELL_CAST, op->map, op, caster, NULL, stringarg, type);
318 
319  /* So the plugin's return value can affect the returned value. */
320  if (retval) {
321  return retval - 1;
322  }
323  }
324 
325  if (caster->type == PLAYER) {
326  CONTR(caster)->stat_spells_cast++;
327  CONTR(caster)->last_combat = pticks;
328  }
329 
330  /* We need to calculate the spell point cost before the spell actually
331  * does something, otherwise the following can happen (example):
332  * Player has 7 mana left, kills a monster with magic bullet (which costs 7
333  * mana) while standing right next to it, magic bullet kills the monster
334  * before
335  * we reach the return here, player levels up, cost of magic bullet
336  * increases
337  * from 7 to 8. So the function would return 8 instead of 7, resulting in
338  * the
339  * player's mana being -1. */
340  if (item != CAST_NPC) {
341  spell_cost = SP_level_spellpoint_cost(caster, type, -1);
342  }
343 
344  switch ((enum spellnrs) type) {
345  case SP_RESTORATION:
346  case SP_CURE_CONFUSION:
347  case SP_MINOR_HEAL:
348  case SP_GREATER_HEAL:
349  case SP_CURE_POISON:
350  case SP_CURE_DISEASE:
351  success = cast_heal(op, caster, SK_level(caster), target, type);
352  break;
353 
354  case SP_REMOVE_DEPLETION:
355  success = cast_remove_depletion(op, target);
356  break;
357 
358  case SP_REMOVE_CURSE:
359  case SP_REMOVE_DAMNATION:
360  success = remove_curse(op, target, type, item);
361  break;
362 
363  case SP_STRENGTH:
364  case SP_PROT_COLD:
365  case SP_PROT_FIRE:
366  case SP_PROT_ELEC:
367  case SP_PROT_POISON:
368  success = cast_change_attr(op, caster, target, type);
369  break;
370 
371  case SP_IDENTIFY:
372  success = cast_identify(target, SK_level(caster), NULL, IDENTIFY_NORMAL);
373  break;
374 
375  /* Spells after this use direction and not a target */
376  case SP_ICESTORM:
377  case SP_FIRESTORM:
378  case SP_HOLYWORD:
379  success = cast_cone(op, caster, dir, duration, type, spellarch[type]);
380  break;
381 
382  case SP_PROBE:
383 
384  if (!dir) {
385  examine(op, op, NULL);
386  success = 1;
387  } else {
388  success = fire_arch_from_position(op, caster, op->x, op->y, dir, spellarch[type], type, NULL);
389  }
390 
391  break;
392 
393  case SP_BULLET:
394  case SP_CAUSE_LIGHT:
395  case SP_MAGIC_MISSILE:
396  success = fire_arch_from_position(op, caster, op->x, op->y, dir, spellarch[type], type, target);
397  break;
398 
399  case SP_WOR:
400  success = cast_wor(op, caster);
401  break;
402 
403  case SP_CREATE_FOOD:
404  success = cast_create_food(op, caster, dir, stringarg);
405  break;
406 
407  case SP_CHARGING:
408  success = recharge(op);
409  break;
410 
411  case SP_CONSECRATE:
412  success = cast_consecrate(op);
413  break;
414 
415  case SP_CAUSE_COLD:
416  case SP_CAUSE_FLU:
417  case SP_CAUSE_LEPROSY:
418  case SP_CAUSE_SMALLPOX:
419  case SP_CAUSE_PNEUMONIC_PLAGUE:
420  success = cast_cause_disease(op, caster, dir, spellarch[type], type);
421  break;
422 
423  case SP_FINGER_DEATH:
424  success = finger_of_death(op, target);
425  break;
426 
427  case SP_POISON_FOG:
428  case SP_METEOR:
429  case SP_ASTEROID:
430  success = fire_arch_from_position(op, caster, op->x, op->y, dir, spellarch[type], type, NULL);
431  break;
432 
433  case SP_METEOR_SWARM:
434  success = 1;
435  fire_swarm(op, caster, dir, spellarch[type], SP_METEOR, 3, 0);
436  break;
437 
438  case SP_FROST_NOVA:
439  success = 1;
440  fire_swarm(op, caster, dir, spellarch[type], SP_ASTEROID, 3, 0);
441  break;
442 
443  case SP_BULLET_SWARM:
444  success = 1;
445  fire_swarm(op, caster, dir, spellarch[type], SP_BULLET, 5, 0);
446  break;
447 
448  case SP_BULLET_STORM:
449  success = 1;
450  fire_swarm(op, caster, dir, spellarch[type], SP_BULLET, 3, 0);
451  break;
452 
453  case SP_DESTRUCTION:
454  success = 1;
455  cast_destruction(op, caster, 5 + op->stats.Int);
456  break;
457 
458  case SP_TRANSFORM_WEALTH:
459  success = cast_transform_wealth(op);
460  break;
461 
462  case SP_RAIN_HEAL:
463  case SP_PARTY_HEAL:
464  success = cast_heal_around(op, SK_level(caster), type);
465  break;
466 
467  case SP_FROSTBOLT:
468  case SP_FIREBOLT:
469  case SP_LIGHTNING:
470  case SP_FORKED_LIGHTNING:
471  case SP_NEGABOLT:
472  success = fire_bolt(op, caster, dir, type);
473  break;
474 
475  default:
476  LOG(BUG, "Invalid spell: %d", type);
477  break;
478  }
479 
480  play_sound_map(op->map, CMD_SOUND_EFFECT, spells[type].sound, op->x, op->y, 0, 0);
481 
482  if (item == CAST_NPC) {
483  return success;
484  }
485 
486  return success ? spell_cost : 0;
487 }
488 
501 int cast_create_obj(object *op, object *new_op, int dir)
502 {
503  mapstruct *mt;
504  int xt, yt;
505 
506  xt = op->x + freearr_x[dir];
507  yt = op->y + freearr_y[dir];
508 
509  if (!(mt = get_map_from_coord(op->map, &xt, &yt))) {
510  return 0;
511  }
512 
513  if (dir && blocked(op, mt, xt, yt, op->terrain_flag)) {
514  draw_info(COLOR_WHITE, op, "Something is in the way.\nYou cast it at your feet.");
515  dir = 0;
516  }
517 
518  xt = op->x + freearr_x[dir];
519  yt = op->y + freearr_y[dir];
520 
521  if (!(mt = get_map_from_coord(op->map, &xt, &yt))) {
522  return 0;
523  }
524 
525  new_op->x = xt;
526  new_op->y = yt;
527  new_op->map = mt;
528  object_insert_map(new_op, mt, op, 0);
529  return dir;
530 }
531 
545 int fire_bolt(object *op, object *caster, int dir, int type)
546 {
547  object *tmp;
548 
549  if (!spellarch[type]) {
550  return 0;
551  }
552 
553  if (!dir) {
554  draw_info(COLOR_WHITE, op, "You can't fire that at yourself!");
555  return 0;
556  }
557 
558  if (wall(op->map, op->x + freearr_x[dir], op->y + freearr_y[dir])) {
559  draw_info(COLOR_WHITE, op, "There is something in the way.");
560  return 0;
561  }
562 
563  tmp = arch_to_object(spellarch[type]);
564 
565  if (!tmp) {
566  return 0;
567  }
568 
569  int dam = SP_level_dam_adjust(caster, type, false);
570  dam = MIN(dam, INT16_MAX);
571  tmp->stats.dam = (int16_t) dam;
572  tmp->last_sp = spells[type].bdur + SP_level_strength_adjust(caster, type);
573 
574  tmp->direction = dir;
575  tmp->x = op->x;
576  tmp->y = op->y;
577 
578  object_owner_set(tmp, op);
579  tmp->level = SK_level(caster);
580 
581  if (QUERY_FLAG(tmp, FLAG_IS_TURNABLE)) {
582  SET_ANIMATION(tmp, (NUM_ANIMATIONS(tmp) / NUM_FACINGS(tmp)) * tmp->direction);
583  }
584 
585  tmp = object_insert_map(tmp, op->map, op, 0);
586 
587  if (!tmp) {
588  return 0;
589  }
590 
591  object_process(tmp);
592 
593  return 1;
594 }
595 
615 int fire_arch_from_position(object *op, object *caster, int16_t x, int16_t y, int dir, struct archetype *at, int type, object *target)
616 {
617  object *tmp, *env;
618 
619  if (at == NULL) {
620  return 0;
621  }
622 
623  for (env = op; env->env != NULL; env = env->env) {
624  }
625 
626  if (env->map == NULL) {
627  return 0;
628  }
629 
630  tmp = arch_to_object(at);
631 
632  if (tmp == NULL) {
633  return 0;
634  }
635 
636  tmp->stats.sp = type;
637  int dam = SP_level_dam_adjust(caster, type, false);
638  dam = MIN(dam, INT16_MAX);
639  tmp->stats.dam = (int16_t) dam;
640  tmp->stats.hp = spells[type].bdur + SP_level_strength_adjust(caster, type);
641  tmp->x = x, tmp->y = y;
642  tmp->direction = dir;
643 
644  if (target) {
645  tmp->enemy = target;
646  tmp->enemy_count = target->count;
647  }
648 
649  if (object_owner(op) != NULL) {
650  object_owner_copy(tmp, op);
651  } else {
652  object_owner_set(tmp, op);
653  }
654 
655  tmp->level = SK_level(caster);
656 
657  if (QUERY_FLAG(tmp, FLAG_IS_TURNABLE)) {
658  SET_ANIMATION(tmp, (NUM_ANIMATIONS(tmp) / NUM_FACINGS(tmp)) * dir);
659  }
660 
661  if ((tmp = object_insert_map(tmp, op->map, op, 0)) == NULL) {
662  return 1;
663  }
664 
665  object_process(tmp);
666 
667  return 1;
668 }
669 
687 int cast_cone(object *op, object *caster, int dir, int strength, int spell_type, struct archetype *spell_arch)
688 {
689  object *tmp;
690  int i, success = 0, range_min = -1, range_max = 1;
691  uint32_t count_ref;
692 
693  if (!dir) {
694  range_min = -3, range_max = 4, strength /= 2;
695  }
696 
697  /* Our initial spell object */
698  tmp = arch_to_object(spell_arch);
699 
700  if (!tmp) {
701  LOG(BUG, "arch_to_object() failed!? (%s)", spell_arch->name);
702  return 0;
703  }
704 
705  count_ref = tmp->count;
706 
707  for (i = range_min; i <= range_max; i++) {
708  int x = op->x + freearr_x[absdir(dir + i)], y = op->y + freearr_y[absdir(dir + i)];
709 
710  if (wall(op->map, x, y)) {
711  continue;
712  }
713 
714  success = 1;
715 
716  if (!tmp) {
717  tmp = arch_to_object(spell_arch);
718  }
719 
720  object_owner_set(tmp, op);
721  object_owner_copy(tmp, op);
722  /* *very* important - miss this and the spells go really wild! */
723  tmp->weight_limit = count_ref;
724 
725  tmp->level = SK_level(caster);
726  tmp->x = x, tmp->y = y;
727 
728  if (dir) {
729  tmp->stats.sp = dir;
730  } else {
731  tmp->stats.sp = i;
732  }
733 
734  tmp->stats.hp = strength;
735  int dam = SP_level_dam_adjust(caster, spell_type, false);
736  dam = MIN(dam, INT16_MAX);
737  tmp->stats.dam = (int16_t) dam;
738  tmp->stats.maxhp = tmp->count;
739 
740  if (!QUERY_FLAG(tmp, FLAG_FLYING)) {
741  LOG(DEBUG, "arch %s doesn't have flying 1", spell_arch->name);
742  }
743 
744  if ((!QUERY_FLAG(tmp, FLAG_WALK_ON) || !QUERY_FLAG(tmp, FLAG_FLY_ON)) && tmp->stats.dam) {
745  LOG(DEBUG, "arch %s doesn't have walk_on 1 and fly_on 1", spell_arch->name);
746  }
747 
748  if (!object_insert_map(tmp, op->map, op, 0)) {
749  return 0;
750  }
751 
752  if (tmp->other_arch) {
753  cone_drop(tmp);
754  }
755 
756  tmp = NULL;
757  }
758 
759  /* Can happen when we can't drop anything */
760  if (tmp) {
761  /* Was not inserted */
762  if (!QUERY_FLAG(tmp, FLAG_REMOVED)) {
763  object_remove(tmp, 0);
764  }
765 
766  object_destroy(tmp);
767  }
768 
769  return success;
770 }
771 
777 void cone_drop(object *op)
778 {
779  object *new_ob = arch_to_object(op->other_arch);
780 
781  new_ob->x = op->x;
782  new_ob->y = op->y;
783  new_ob->stats.food = op->stats.hp;
784  new_ob->level = op->level;
785  object_owner_set(new_ob, op->owner);
786 
787  if (op->chosen_skill) {
788  new_ob->chosen_skill = op->chosen_skill;
789  }
790 
791  object_insert_map(new_ob, op->map, op, 0);
792 }
793 
799 void explode_object(object *op)
800 {
801  HARD_ASSERT(op != NULL);
802 
803  play_sound_map(op->map, CMD_SOUND_EFFECT, "explosion.ogg", op->x, op->y, 0, 0);
804 
805  if (op->other_arch == NULL) {
806  log_error("Object without other_arch: %s", object_get_str(op));
807  object_remove(op, 0);
808  object_destroy(op);
809  return;
810  }
811 
812  object *caster = object_owner(op);
813  if (caster == NULL) {
814  caster = op;
815  }
816 
817  cast_cone(op,
818  caster,
819  0,
820  spells[op->stats.sp].bdur,
821  op->stats.sp,
822  op->other_arch);
823 
825  attack_hit_map(op, 0, false);
826  if (OBJECTS_DESTROYED(op)) {
827  return;
828  }
830 
831  object_remove(op, 0);
832  object_destroy(op);
833 }
834 
843 void check_fired_arch(object *op)
844 {
845  HARD_ASSERT(op != NULL);
846 
847  if (!blocked(op, op->map, op->x, op->y, op->terrain_flag)) {
848  return;
849  }
850 
851  if (op->other_arch != NULL) {
852  explode_object(op);
853  return;
854  }
855 
856  object *hitter = OWNER(op);
857  hitter = HEAD(hitter);
858 
859  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp) {
860  tmp = HEAD(tmp);
861  if (!IS_LIVE(tmp)) {
862  continue;
863  }
864 
865  if (hitter == tmp || is_friend_of(hitter, tmp)) {
866  continue;
867  }
868 
870  int dam = attack_hit(tmp, op, op->stats.dam);
871  if (OBJECTS_DESTROYED(op)) {
872  return;
873  }
874 
875  op->stats.dam -= dam;
876  if (op->stats.dam < 0) {
877  object_remove(op, 0);
878  object_destroy(op);
879  return;
880  }
882  } FOR_MAP_FINISH();
883 }
884 
896 int find_target_for_spell(object *op, object **target, uint32_t flags)
897 {
898  object *tmp;
899 
900  /* Default target is nothing. */
901  *target = NULL;
902 
903  /* We cast something on the map... No target */
904  if (flags & SPELL_DESC_DIRECTION) {
905  return 1;
906  }
907 
908  /* A player has invoked this spell. */
909  if (op->type == PLAYER) {
910  /* Try to cast on self but only when really no friendly or enemy is set.
911  * */
912  if ((flags & SPELL_DESC_SELF) && !(flags & (SPELL_DESC_ENEMY | SPELL_DESC_FRIENDLY))) {
913  /* Self... and no other tests */
914  *target = op;
915  return 1;
916  }
917 
918  tmp = CONTR(op)->target_object;
919 
920  /* Let's check our target - we have one? friend or enemy? */
921  if (!tmp || !OBJECT_ACTIVE(tmp) || tmp == CONTR(op)->ob || CONTR(op)->target_object_count != tmp->count) {
922  /* Can we cast this on self? */
923  if (flags & SPELL_DESC_SELF) {
924  /* Right, we are target */
925  *target = op;
926  return 1;
927  }
928  } else {
929  /* We have a target and it's not self */
930 
931  if (is_friend_of(op, tmp)) {
932  if (flags & SPELL_DESC_FRIENDLY) {
933  *target = tmp;
934  return 1;
935  }
936 
937  if (flags & SPELL_DESC_SELF) {
938  *target = op;
939  return 1;
940  }
941 
942  /* Can't cast unfriendly spells on friendly creatures, but we
943  * set target
944  * so the message player gets is accurate. */
945  if (flags & SPELL_DESC_ENEMY) {
946  *target = tmp;
947  return 0;
948  }
949  } else {
950  if (flags & SPELL_DESC_ENEMY) {
951  *target = tmp;
952  return 1;
953  }
954 
955  if (flags & SPELL_DESC_SELF) {
956  *target = op;
957  return 1;
958  }
959  }
960  }
961  } else {
962  /* A monster or rune/firewall/etc */
963 
964  if ((flags & SPELL_DESC_SELF) && !(flags & (SPELL_DESC_ENEMY | SPELL_DESC_FRIENDLY))) {
965  *target = op;
966  return 1;
967  } else if ((flags & SPELL_DESC_ENEMY) && op->enemy && OBJECT_ACTIVE(op->enemy) && op->enemy->count == op->enemy_count) {
968  *target = op->enemy;
969  return 1;
970  } else {
971  *target = op;
972  return 1;
973  }
974  }
975 
976  /* Invalid target/spell or whatever */
977  return 0;
978 }
979 
991 int
992 SP_level_dam_adjust (object *caster, int spell_type, bool exact)
993 {
994  HARD_ASSERT(caster != NULL);
995  SOFT_ASSERT_RC(spell_type >= 0 && spell_type < NROFREALSPELLS, 0,
996  "Invalid spell ID: %d", spell_type);
997 
998  int level = SK_level(caster);
999 
1000  /* Sanity check */
1001  if (unlikely(level <= 0 || level > MAXLEVEL)) {
1002  log_error("Object %s has invalid level %d",
1003  object_get_str(caster), level);
1004  level = MAX(1, MIN(MAXLEVEL, level));
1005  }
1006 
1007  if (spells[spell_type].bdam == 0) {
1008  return 0;
1009  }
1010 
1011  double dam = spells[spell_type].bdam;
1012  dam *= LEVEL_DAMAGE(level);
1013  dam *= PATH_DMG_MULT(caster, find_spell(spell_type));
1014 
1015  if (caster->type == PLAYER) {
1016  dam += dam * spell_dam_bonus[caster->stats.Pow];
1017  }
1018 
1019  if (dam < 1.0) {
1020  dam = 1.0;
1021  }
1022 
1023  if (exact) {
1024  return (int) dam;
1025  }
1026 
1027  return rndm(dam * 0.8 + 0.5, dam);
1028 }
1029 
1039 int SP_level_strength_adjust(object *caster, int spell_type)
1040 {
1041  int level = SK_level(caster);
1042  int adj = (level);
1043 
1044  if (adj < 0) {
1045  adj = 0;
1046  }
1047 
1048  if (spells[spell_type].ldur) {
1049  adj /= spells[spell_type].ldur;
1050  } else {
1051  adj = 0;
1052  }
1053 
1054  return adj;
1055 }
1056 
1072 int SP_level_spellpoint_cost(object *caster, int spell_type, int caster_level)
1073 {
1074  spell_struct *s = find_spell(spell_type);
1075  int level = (caster_level == -1 ? SK_level(caster) : caster_level), sp;
1076 
1077  if (spells[spell_type].spl) {
1078  sp = (int) (spells[spell_type].sp * (1.0 + (MAX(0, (float) (level) / (float) spells[spell_type].spl))));
1079  } else {
1080  sp = spells[spell_type].sp;
1081  }
1082 
1083  if (caster_level == -1) {
1084  sp = (int) ((float) sp * (float) PATH_SP_MULT(caster, s));
1085  }
1086 
1087  return sp;
1088 }
1089 
1109 void fire_swarm(object *op, object *caster, int dir, struct archetype *swarm_type, int spell_type, int n, int magic)
1110 {
1111  object *tmp = arch_get("swarm_spell");
1112 
1113  tmp->x = op->x;
1114  tmp->y = op->y;
1115  /* Needed so that if swarm elements kill, caster gets xp. */
1116  object_owner_set(tmp, op);
1117  /* Needed later, to get level dep. right.*/
1118  tmp->level = SK_level(caster);
1119  /* Needed later, see move_swarm_spell */
1120  tmp->stats.sp = spell_type;
1121 
1122  tmp->magic = magic;
1123  /* n in swarm */
1124  tmp->stats.hp = n;
1125  /* The archetype of the things to be fired */
1126  tmp->other_arch = swarm_type;
1127  tmp->direction = dir;
1128 
1129  object_insert_map(tmp, op->map, op, 0);
1130 }
1131 
1140 void spell_failure_raw_mana(object *caster, int level)
1141 {
1142  object *tmp;
1143  tag_t count_ref;
1144 
1145  tmp = arch_get("raw_mana");
1146  count_ref = tmp->count;
1147 
1148  for (int i = 0; i <= SIZEOFFREE1; i++) {
1149  if (tmp == NULL) {
1150  tmp = arch_get("raw_mana");
1151  }
1152 
1153  tmp->weight_limit = count_ref;
1154  tmp->level = caster->level;
1155  tmp->stats.sp = i;
1156  tmp->stats.hp = MIN(10, 3 + level / 5);
1157  tmp->stats.maxhp = tmp->count;
1158  tmp->stats.dam = level;
1159 
1160  tmp->x = caster->x + freearr_x[i];
1161  tmp->y = caster->y + freearr_y[i];
1162 
1163  if (!object_insert_map(tmp, caster->map, caster, 0)) {
1164  continue;
1165  }
1166 
1167  tmp = NULL;
1168  }
1169 }
1170 
1178 void spell_failure(object *caster, int level)
1179 {
1180  bool punished = false;
1181 
1182  if (level >= 15) {
1183  if (rndm_chance(MAX(1, (MAXLEVEL - level * 1.05) / 2))) {
1184  draw_info(COLOR_RED, caster, "The wild magic confuses you!");
1185  attack_perform_confusion(caster);
1186  punished = true;
1187  }
1188 
1189  if (rndm_chance(MAX(1, (MAXLEVEL - level * 1.10) / 3))) {
1190  draw_info(COLOR_RED, caster, "The wild magic paralyzes you!");
1191  attack_peform_paralyze(caster, level * 2);
1192  punished = true;
1193  }
1194 
1195  if (rndm_chance(MAX(1, (MAXLEVEL - level * 1.15) / 4))) {
1196  draw_info(COLOR_RED, caster, "The wild magic blinds you!");
1197  attack_perform_blind(caster, caster, level * 2);
1198  punished = true;
1199  }
1200 
1201  if (rndm_chance(MAX(1, (MAXLEVEL - level * 1.2) / 5))) {
1202  draw_info(COLOR_RED, caster,
1203  "You unleash an uncontrolled blast of raw mana!");
1204  spell_failure_raw_mana(caster, level * 2);
1205  punished = true;
1206  }
1207  }
1208 
1209  if (!punished) {
1210  draw_info(COLOR_RED, caster, "The wild magic drains your mana!");
1211  caster->stats.sp -= rndm(1, level) * 1.75;
1212 
1213  if (caster->stats.sp < 0) {
1214  caster->stats.sp = 0;
1215  }
1216  }
1217 }
1218 
1229 int
1230 spell_get_random (int level, int flags)
1231 {
1232  int spell_choices[NROFREALSPELLS];
1233  int num_spells = 0;
1234 
1235  /* Collect the list of spells we can choose from. */
1236  for (int i = 0; i < NROFREALSPELLS; i++) {
1237  if (level < spells[i].at->clone.level) {
1238  continue;
1239  }
1240 
1241  if (!(spells[i].spell_use & flags)) {
1242  continue;
1243  }
1244 
1245  spell_choices[num_spells++] = i;
1246  }
1247 
1248  if (num_spells == 0) {
1249  return SP_NO_SPELL;
1250  }
1251 
1252  /* Select a random spell from the list of choices. */
1253  return spell_choices[rndm(0, num_spells - 1)];
1254 }
void attack_perform_confusion(object *op)
Definition: attack.c:1294
#define MAP_NOHARM(m)
Definition: map.h:108
void object_destroy(object *ob)
Definition: object.c:1441
shstr * name
Definition: map.h:553
void init_spells(void)
Definition: spell_util.c:61
#define MSP_EXTRA_NO_HARM
Definition: map.h:320
int remove_curse(object *op, object *target, int type, int src)
Definition: spell_effect.c:848
#define SPELL_DESC_ENEMY
Definition: spells.h:124
#define OBJECT_ACTIVE(_ob_)
Definition: object.h:551
int cast_create_food(object *op, object *caster, int dir, const char *stringarg)
Definition: spell_effect.c:138
void spell_failure(object *caster, int level)
Definition: spell_util.c:1178
unsigned int distance
Definition: map.h:775
tag_t enemy_count
Definition: object.h:216
void cast_destruction(object *op, object *caster, int dam)
Definition: spell_effect.c:259
#define NUM_FACINGS(ob)
Definition: global.h:300
#define MEVENT_SPELL_CAST
Definition: plugin.h:125
int recharge(object *op)
Definition: spell_effect.c:71
uint8_t type
One of operation types.
Definition: sound_ambient.c:45
void check_fired_arch(object *op)
Definition: spell_util.c:843
int cast_heal_around(object *op, int level, int type)
Definition: spell_effect.c:326
int SP_level_strength_adjust(object *caster, int spell_type)
Definition: spell_util.c:1039
#define NROFREALSPELLS
Definition: define.h:664
#define SIZEOFFREE1
Definition: define.h:654
mapstruct * get_map_from_coord(mapstruct *m, int *x, int *y)
Definition: map.c:1869
int SK_level(object *op)
Definition: skill_util.c:470
int range
Definition: spells.h:147
#define SPELL_DESC_DIRECTION
Definition: spells.h:118
#define SET_ANIMATION(ob, newanim)
Definition: global.h:282
#define FLAG_FLY_ON
Definition: define.h:968
int spell_use
Definition: spells.h:186
int cast_consecrate(object *op)
const char * sound
Definition: spells.h:183
int blocked(object *op, mapstruct *m, int x, int y, int terrain)
Definition: map.c:598
int16_t last_sp
Definition: object.h:313
int wall(mapstruct *m, int x, int y)
Definition: map.c:486
int cast_transform_wealth(object *op)
object * arch_get(const char *name)
Definition: arch.c:430
static double spell_dam_bonus[MAX_STAT+1]
Definition: spell_util.c:48
void object_process(object *op)
int cast_wor(object *op, object *caster)
Definition: spell_effect.c:211
void attack_hit_map(object *op, int dir, bool multi_reduce)
Definition: attack.c:830
static int absdir(int d)
Definition: define.h:1838
#define IS_LIVE(op)
Definition: define.h:841
#define PLAYER
Definition: define.h:122
#define SPELL_DESC_SELF
Definition: spells.h:120
int SP_level_spellpoint_cost(object *caster, int spell_type, int caster_level)
Definition: spell_util.c:1072
int16_t sp
Definition: living.h:78
#define OBJECTS_DESTROYED_BEGIN(...)
Definition: object.h:765
#define FLAG_IS_TURNABLE
Definition: define.h:960
#define QUERY_FLAG(xyz, p)
Definition: define.h:761
struct obj * enemy
Definition: object.h:196
struct archetype * other_arch
Definition: object.h:228
int8_t Int
Definition: living.h:112
void object_remove(object *op, int flags)
Definition: object.c:1623
void spell_failure_raw_mana(object *caster, int level)
Definition: spell_util.c:1140
int32_t hp
Definition: living.h:72
int cast_spell(object *op, object *caster, int dir, int type, int ability, int item, const char *stringarg)
Definition: spell_util.c:192
char * object_get_name_s(const object *op, const object *caller)
Definition: item.c:398
int cast_remove_depletion(object *op, object *target)
Definition: spell_effect.c:759
struct obj * chosen_skill
Definition: object.h:210
int16_t y
Definition: object.h:276
int32_t maxhp
Definition: living.h:75
uint32_t path_denied
Definition: object.h:261
const char * object_get_str(const object *op)
Definition: object.c:3151
int8_t direction
Definition: object.h:350
spell_struct * find_spell(int spelltype)
Definition: spell_util.c:160
Definition: arch.h:40
int is_friend_of(object *op, object *obj)
Definition: monster.c:1685
void attack_perform_blind(object *op, object *hitter, double dam)
Definition: attack.c:1342
#define CAST_NPC
Definition: spells.h:288
struct mapdef * map
Definition: object.h:139
#define SP_NO_SPELL
Definition: spells.h:202
int16_t dam
Definition: living.h:87
int cast_create_obj(object *op, object *new_op, int dir)
Definition: spell_util.c:501
const char * name
Definition: object.h:168
#define SPELL_DESC_TOWN
Definition: spells.h:116
struct obj * env
Definition: object.h:130
struct archetype * at
Definition: spells.h:198
void explode_object(object *op)
Definition: spell_util.c:799
#define MAP_NOMAGIC(m)
Definition: map.h:102
object * arch_to_object(archetype_t *at)
Definition: arch.c:446
uint32_t flags
Definition: spells.h:189
int cast_change_attr(object *op, object *caster, object *target, int spell_type)
Definition: spell_effect.c:638
int cast_heal(object *op, object *caster, int level, object *target, int spell_type)
Definition: spell_effect.c:404
#define OBJECTS_DESTROYED(obj)
Definition: object.h:811
int insert_spell_effect(const char *archname, mapstruct *m, int x, int y)
Definition: spell_util.c:118
#define FLAG_FLYING
Definition: define.h:918
int trigger_map_event(int event_id, mapstruct *m, object *activator, object *other, object *other2, const char *text, int parm)
Definition: plugins.c:416
int find_target_for_spell(object *op, object **target, uint32_t flags)
Definition: spell_util.c:896
#define HEAD(op)
Definition: object.h:657
#define FOR_MAP_FINISH()
Definition: define.h:1759
int blocks_magic(mapstruct *m, int x, int y)
Definition: map.c:529
int16_t x
Definition: object.h:273
void fire_swarm(object *op, object *caster, int dir, struct archetype *swarm_type, int spell_type, int n, int magic)
Definition: spell_util.c:1109
#define FLAG_REMOVED
Definition: define.h:930
int cast_cone(object *op, object *caster, int dir, int strength, int spell_type, struct archetype *spell_arch)
Definition: spell_util.c:687
int fire_arch_from_position(object *op, object *caster, int16_t x, int16_t y, int dir, struct archetype *at, int type, object *target)
Definition: spell_util.c:615
object * object_insert_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1741
int bdur
Definition: spells.h:162
spell_struct spells[NROFREALSPELLS]
Definition: spellist.h:34
void play_sound_map(mapstruct *map, int type, const char *filename, int x, int y, int loop, int volume)
Definition: sounds.c:159
uint32_t weight_limit
Definition: object.h:252
#define MAXLEVEL
Definition: global.h:221
struct map_event * events
Definition: map.h:583
#define LEVEL_DAMAGE(level)
Definition: living.h:61
void object_owner_set(object *op, object *owner)
Definition: object.c:788
#define OBJECTS_DESTROYED_END()
Definition: object.h:816
int SP_level_dam_adjust(object *caster, int spell_type, bool exact)
Definition: spell_util.c:992
#define RV_DIAGONAL_DISTANCE
Definition: map.h:809
void attack_peform_paralyze(object *op, double dam)
Definition: attack.c:1399
struct obj * owner
Definition: object.h:207
#define NUM_ANIMATIONS(ob)
Definition: global.h:298
uint32_t path
Definition: spells.h:192
tag_t count
Definition: object.h:142
int get_rangevector_from_mapcoords(mapstruct *map1, int x, int y, mapstruct *map2, int x2, int y2, rv_vector *retval, int flags)
Definition: map.c:2297
living stats
Definition: object.h:481
int attack_hit(object *op, object *hitter, int dam)
Definition: attack.c:669
struct archetype * spellarch[NROFREALSPELLS]
Definition: spell_util.c:43
int freearr_x[SIZEOFFREE]
Definition: object.c:84
uint8_t type
Definition: object.h:360
int fire_bolt(object *op, object *caster, int dir, int type)
Definition: spell_util.c:545
#define IDENTIFY_NORMAL
Definition: define.h:58
object * object_owner(object *op)
Definition: object.c:857
void examine(object *op, object *tmp, StringBuffer *sb_capture)
Definition: player.c:1521
shstr * name
More definite name, like "kobold".
Definition: arch.h:46
uint8_t extra_flags
Definition: map.h:390
uint16_t terrain_flag
Definition: object.h:301
int spell_get_random(int level, int flags)
Definition: spell_util.c:1230
int bdam
Definition: spells.h:159
int cast_cause_disease(object *op, object *caster, int dir, struct archetype *disease_arch, int type)
int8_t Pow
Definition: living.h:115
int ldur
Definition: spells.h:168
#define FLAG_WALK_ON
Definition: define.h:904
#define CAST_POTION
Definition: spells.h:283
Definition: map.h:536
int finger_of_death(object *op, object *target)
#define CAST_NORMAL
Definition: spells.h:275
int8_t level
Definition: object.h:347
int freearr_y[SIZEOFFREE]
Definition: object.c:99
spellnrs
Definition: spells.h:215
int cast_identify(object *op, int level, object *single_ob, int mode)
Definition: spell_effect.c:997
void object_owner_copy(object *op, object *clone_ob)
Definition: object.c:824
int64_t value
Definition: object.h:240
int8_t magic
Definition: object.h:341
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:1752
object clone
An object from which to do object_copy().
Definition: arch.h:47
static object * OWNER(object *op)
Definition: object.h:979
archetype_t * arch_find(const char *name)
Definition: arch.c:407
#define SPELL_DESC_FRIENDLY
Definition: spells.h:122
void cone_drop(object *op)
Definition: spell_util.c:777
#define MAX_STAT
Definition: define.h:47
int16_t food
Definition: living.h:84