1 | |
|
|
2 | /* |
|
|
3 | * static char *rcsid_spell_attack_c = |
|
|
4 | * "$Id: spell_attack.C,v 1.9 2006/09/10 15:59:57 root Exp $"; |
|
|
5 | */ |
|
|
6 | |
|
|
7 | |
|
|
8 | /* |
1 | /* |
9 | CrossFire, A Multiplayer game for X-windows |
2 | CrossFire, A Multiplayer game for X-windows |
10 | |
3 | |
11 | Copyright (C) 2002-2003 Mark Wedel & Crossfire Development Team |
4 | Copyright (C) 2002-2003 Mark Wedel & Crossfire Development Team |
12 | Copyright (C) 1992 Frank Tore Johansen |
5 | Copyright (C) 1992 Frank Tore Johansen |
… | |
… | |
23 | |
16 | |
24 | You should have received a copy of the GNU General Public License |
17 | You should have received a copy of the GNU General Public License |
25 | along with this program; if not, write to the Free Software |
18 | along with this program; if not, write to the Free Software |
26 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
27 | |
20 | |
28 | The authors can be reached via e-mail at crossfire-devel@real-time.com |
21 | The authors can be reached via e-mail at <crossfire@schmorp.de> |
29 | */ |
22 | */ |
30 | |
23 | |
31 | /* This file contains all the spell attack code. Grouping this code |
24 | /* This file contains all the spell attack code. Grouping this code |
32 | * together should hopefully make it easier to find the relevent bits |
25 | * together should hopefully make it easier to find the relevent bits |
33 | * of code |
26 | * of code |
… | |
… | |
185 | { |
178 | { |
186 | remove_ob (op); |
179 | remove_ob (op); |
187 | free_object (op); |
180 | free_object (op); |
188 | return; |
181 | return; |
189 | } |
182 | } |
|
|
183 | |
190 | hit_map (op, 0, op->attacktype, 1); |
184 | hit_map (op, 0, op->attacktype, 1); |
191 | |
185 | |
192 | if (!op->direction) |
186 | if (!op->direction) |
193 | return; |
187 | return; |
194 | |
188 | |
… | |
… | |
468 | |
462 | |
469 | copy_owner (tmp, op); |
463 | copy_owner (tmp, op); |
470 | tmp->skill = op->skill; |
464 | tmp->skill = op->skill; |
471 | |
465 | |
472 | owner = get_owner (op); |
466 | owner = get_owner (op); |
|
|
467 | |
473 | if ((tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) && owner && !tailor_god_spell (tmp, owner)) |
468 | if ((tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) && owner && !tailor_god_spell (tmp, owner)) |
474 | { |
469 | { |
475 | remove_ob (op); |
470 | remove_ob (op); |
476 | free_object (op); |
471 | free_object (op); |
477 | return; |
472 | return; |
478 | } |
473 | } |
|
|
474 | |
479 | tmp->x = op->x; |
475 | tmp->x = op->x; |
480 | tmp->y = op->y; |
476 | tmp->y = op->y; |
481 | |
477 | |
482 | /* special for bombs - it actually has sane values for these */ |
478 | /* special for bombs - it actually has sane values for these */ |
483 | if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB) |
479 | if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB) |
… | |
… | |
931 | tmp->y = sy; |
927 | tmp->y = sy; |
932 | tmp->attacktype = spell->attacktype; |
928 | tmp->attacktype = spell->attacktype; |
933 | |
929 | |
934 | /* holy word stuff */ |
930 | /* holy word stuff */ |
935 | if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER)) |
931 | if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER)) |
936 | { |
|
|
937 | if (!tailor_god_spell (tmp, op)) |
932 | if (!tailor_god_spell (tmp, op)) |
938 | return 0; |
933 | return 0; |
939 | } |
|
|
940 | |
934 | |
941 | if (dir) |
935 | if (dir) |
942 | tmp->stats.sp = dir; |
936 | tmp->stats.sp = dir; |
943 | else |
937 | else |
944 | tmp->stats.sp = i; |
938 | tmp->stats.sp = i; |
… | |
… | |
950 | { |
944 | { |
951 | tmp->range /= 4; |
945 | tmp->range /= 4; |
952 | if (tmp->range < 2 && spell->range >= 2) |
946 | if (tmp->range < 2 && spell->range >= 2) |
953 | tmp->range = 2; |
947 | tmp->range = 2; |
954 | } |
948 | } |
|
|
949 | |
955 | tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); |
950 | tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); |
956 | tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell); |
951 | tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell); |
957 | |
952 | |
958 | /* Special bonus for fear attacks */ |
953 | /* Special bonus for fear attacks */ |
959 | if (tmp->attacktype & AT_FEAR) |
954 | if (tmp->attacktype & AT_FEAR) |
… | |
… | |
961 | if (caster->type == PLAYER) |
956 | if (caster->type == PLAYER) |
962 | tmp->duration += fear_bonus[caster->stats.Cha]; |
957 | tmp->duration += fear_bonus[caster->stats.Cha]; |
963 | else |
958 | else |
964 | tmp->duration += caster->level / 3; |
959 | tmp->duration += caster->level / 3; |
965 | } |
960 | } |
|
|
961 | |
966 | if (tmp->attacktype & (AT_HOLYWORD | AT_TURN_UNDEAD)) |
962 | if (tmp->attacktype & (AT_HOLYWORD | AT_TURN_UNDEAD)) |
967 | { |
963 | { |
968 | if (caster->type == PLAYER) |
964 | if (caster->type == PLAYER) |
969 | tmp->duration += turn_bonus[caster->stats.Wis] / 5; |
965 | tmp->duration += turn_bonus[caster->stats.Wis] / 5; |
970 | else |
966 | else |
971 | tmp->duration += caster->level / 3; |
967 | tmp->duration += caster->level / 3; |
972 | } |
968 | } |
973 | |
969 | |
974 | |
|
|
975 | if (!(tmp->move_type & MOVE_FLY_LOW)) |
970 | if (!(tmp->move_type & MOVE_FLY_LOW)) |
976 | LOG (llevDebug, "cast_cone(): arch %s doesn't have flying 1\n", &spell->other_arch->name); |
971 | LOG (llevDebug, "cast_cone(): arch %s doesn't have flying 1\n", &spell->other_arch->name); |
977 | |
972 | |
978 | if (!tmp->move_on && tmp->stats.dam) |
973 | if (!tmp->move_on && tmp->stats.dam) |
979 | { |
974 | { |
980 | LOG (llevDebug, "cast_cone(): arch %s doesn't have move_on set\n", &spell->other_arch->name); |
975 | LOG (llevDebug, "cast_cone(): arch %s doesn't have move_on set\n", &spell->other_arch->name); |
981 | } |
976 | } |
|
|
977 | |
982 | insert_ob_in_map (tmp, m, op, 0); |
978 | insert_ob_in_map (tmp, m, op, 0); |
983 | |
979 | |
984 | /* This is used for tracking spells so that one effect doesn't hit |
980 | /* This is used for tracking spells so that one effect doesn't hit |
985 | * a single space too many times. |
981 | * a single space too many times. |
986 | */ |
982 | */ |
987 | tmp->stats.maxhp = tmp->count; |
983 | tmp->stats.maxhp = tmp->count; |
988 | |
984 | |
989 | if (tmp->other_arch) |
985 | if (tmp->other_arch) |
990 | cone_drop (tmp); |
986 | cone_drop (tmp); |
991 | } |
987 | } |
|
|
988 | |
992 | return success; |
989 | return success; |
993 | } |
990 | } |
994 | |
991 | |
995 | /**************************************************************************** |
992 | /**************************************************************************** |
996 | * |
993 | * |
… | |
… | |
1010 | archetype *at; |
1007 | archetype *at; |
1011 | |
1008 | |
1012 | if (op->state != NUM_ANIMATIONS (op) - 1) |
1009 | if (op->state != NUM_ANIMATIONS (op) - 1) |
1013 | return; |
1010 | return; |
1014 | |
1011 | |
1015 | |
|
|
1016 | env = object_get_env_recursive (op); |
1012 | env = object_get_env_recursive (op); |
1017 | |
1013 | |
1018 | if (op->env) |
1014 | if (op->env) |
1019 | { |
1015 | { |
1020 | if (env->map == NULL) |
1016 | if (env->map == NULL) |
… | |
… | |
1042 | |
1038 | |
1043 | /* This copies a lot of the code from the fire bullet, |
1039 | /* This copies a lot of the code from the fire bullet, |
1044 | * but using the cast_bullet isn't really feasible, |
1040 | * but using the cast_bullet isn't really feasible, |
1045 | * so just set up the appropriate values. |
1041 | * so just set up the appropriate values. |
1046 | */ |
1042 | */ |
1047 | at = find_archetype (SPLINT); |
1043 | at = archetype::find (SPLINT); |
1048 | if (at) |
1044 | if (at) |
1049 | { |
1045 | { |
1050 | for (i = 1; i < 9; i++) |
1046 | for (i = 1; i < 9; i++) |
1051 | { |
1047 | { |
1052 | if (out_of_map (op->map, op->x + freearr_x[i], op->y + freearr_x[i])) |
1048 | if (out_of_map (op->map, op->x + freearr_x[i], op->y + freearr_x[i])) |