ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/spell_attack.C
(Generate patch)

Comparing deliantra/server/server/spell_attack.C (file contents):
Revision 1.9 by root, Sun Sep 10 15:59:57 2006 UTC vs.
Revision 1.14 by root, Thu Sep 14 23:13:49 2006 UTC

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
408 * explode. 402 * explode.
409 */ 403 */
410void 404void
411explode_bullet (object *op) 405explode_bullet (object *op)
412{ 406{
413 tag_t op_tag = op->count;
414 object *tmp, *owner; 407 object *tmp, *owner;
415 408
416 if (op->other_arch == NULL) 409 if (op->other_arch == NULL)
417 { 410 {
418 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n"); 411 LOG (llevError, "BUG: explode_bullet(): op without other_arch\n");
457 } 450 }
458 451
459 if (op->attacktype) 452 if (op->attacktype)
460 { 453 {
461 hit_map (op, 0, op->attacktype, 1); 454 hit_map (op, 0, op->attacktype, 1);
462 if (was_destroyed (op, op_tag)) 455 if (op->destroyed ())
463 return; 456 return;
464 } 457 }
465 458
466 /* other_arch contains what this explodes into */ 459 /* other_arch contains what this explodes into */
467 tmp = arch_to_object (op->other_arch); 460 tmp = arch_to_object (op->other_arch);
468 461
469 copy_owner (tmp, op); 462 copy_owner (tmp, op);
470 tmp->skill = op->skill; 463 tmp->skill = op->skill;
471 464
472 owner = get_owner (op); 465 owner = get_owner (op);
466
473 if ((tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) && owner && !tailor_god_spell (tmp, owner)) 467 if ((tmp->attacktype & AT_HOLYWORD || tmp->attacktype & AT_GODPOWER) && owner && !tailor_god_spell (tmp, owner))
474 { 468 {
475 remove_ob (op); 469 remove_ob (op);
476 free_object (op); 470 free_object (op);
477 return; 471 return;
478 } 472 }
473
479 tmp->x = op->x; 474 tmp->x = op->x;
480 tmp->y = op->y; 475 tmp->y = op->y;
481 476
482 /* special for bombs - it actually has sane values for these */ 477 /* special for bombs - it actually has sane values for these */
483 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB) 478 if (op->type == SPELL_EFFECT && op->subtype == SP_BOMB)
508 /* Prevent recursion */ 503 /* Prevent recursion */
509 op->move_on = 0; 504 op->move_on = 0;
510 505
511 insert_ob_in_map (tmp, op->map, op, 0); 506 insert_ob_in_map (tmp, op->map, op, 0);
512 /* remove the firebullet */ 507 /* remove the firebullet */
513 if (!was_destroyed (op, op_tag)) 508 if (!op->destroyed ())
514 { 509 {
515 remove_ob (op); 510 remove_ob (op);
516 free_object (op); 511 free_object (op);
517 } 512 }
518} 513}
524 */ 519 */
525 520
526void 521void
527check_bullet (object *op) 522check_bullet (object *op)
528{ 523{
529 tag_t op_tag = op->count, tmp_tag;
530 object *tmp; 524 object *tmp;
531 int dam, mflags; 525 int dam, mflags;
532 mapstruct *m; 526 mapstruct *m;
533 sint16 sx, sy; 527 sint16 sx, sy;
534 528
550 544
551 for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 545 for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above)
552 { 546 {
553 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 547 if (QUERY_FLAG (tmp, FLAG_ALIVE))
554 { 548 {
555 tmp_tag = tmp->count;
556 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1); 549 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1);
557 if (was_destroyed (op, op_tag) || !was_destroyed (tmp, tmp_tag) || (op->stats.dam -= dam) < 0) 550 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0)
558 { 551 {
559 if (!QUERY_FLAG (op, FLAG_REMOVED)) 552 if (!QUERY_FLAG (op, FLAG_REMOVED))
560 { 553 {
561 remove_ob (op); 554 remove_ob (op);
562 free_object (op); 555 free_object (op);
587 /* peterm: added to make comet leave a trail of burnouts 580 /* peterm: added to make comet leave a trail of burnouts
588 it's an unadulterated hack, but the effect is cool. */ 581 it's an unadulterated hack, but the effect is cool. */
589 if (op->stats.sp == SP_METEOR) 582 if (op->stats.sp == SP_METEOR)
590 { 583 {
591 replace_insert_ob_in_map ("fire_trail", op); 584 replace_insert_ob_in_map ("fire_trail", op);
592 if (was_destroyed (op, op_tag)) 585 if (op->destroyed ())
593 return; 586 return;
594 } /* end addition. */ 587 } /* end addition. */
595#endif 588#endif
596 589
597 /* Reached the end of its life - remove it */ 590 /* Reached the end of its life - remove it */
760 753
761void 754void
762move_cone (object *op) 755move_cone (object *op)
763{ 756{
764 int i; 757 int i;
765 tag_t tag;
766 758
767 /* if no map then hit_map will crash so just ignore object */ 759 /* if no map then hit_map will crash so just ignore object */
768 if (!op->map) 760 if (!op->map)
769 { 761 {
770 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown"); 762 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown");
791 free_object (op); 783 free_object (op);
792 return; 784 return;
793 } 785 }
794#endif 786#endif
795 787
796 tag = op->count;
797 hit_map (op, 0, op->attacktype, 0); 788 hit_map (op, 0, op->attacktype, 0);
798 789
799 /* Check to see if we should push anything. 790 /* Check to see if we should push anything.
800 * Spell objects with weight push whatever they encounter to some 791 * Spell objects with weight push whatever they encounter to some
801 * degree. 792 * degree.
802 */ 793 */
803 if (op->weight) 794 if (op->weight)
804 check_spell_knockback (op); 795 check_spell_knockback (op);
805 796
806 if (was_destroyed (op, tag)) 797 if (op->destroyed ())
807 return; 798 return;
808 799
809 if ((op->duration--) < 0) 800 if ((op->duration--) < 0)
810 { 801 {
811 remove_ob (op); 802 remove_ob (op);
931 tmp->y = sy; 922 tmp->y = sy;
932 tmp->attacktype = spell->attacktype; 923 tmp->attacktype = spell->attacktype;
933 924
934 /* holy word stuff */ 925 /* holy word stuff */
935 if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER)) 926 if ((tmp->attacktype & AT_HOLYWORD) || (tmp->attacktype & AT_GODPOWER))
936 {
937 if (!tailor_god_spell (tmp, op)) 927 if (!tailor_god_spell (tmp, op))
938 return 0; 928 return 0;
939 }
940 929
941 if (dir) 930 if (dir)
942 tmp->stats.sp = dir; 931 tmp->stats.sp = dir;
943 else 932 else
944 tmp->stats.sp = i; 933 tmp->stats.sp = i;
950 { 939 {
951 tmp->range /= 4; 940 tmp->range /= 4;
952 if (tmp->range < 2 && spell->range >= 2) 941 if (tmp->range < 2 && spell->range >= 2)
953 tmp->range = 2; 942 tmp->range = 2;
954 } 943 }
944
955 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 945 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
956 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell); 946 tmp->duration = spell->duration + SP_level_duration_adjust (caster, spell);
957 947
958 /* Special bonus for fear attacks */ 948 /* Special bonus for fear attacks */
959 if (tmp->attacktype & AT_FEAR) 949 if (tmp->attacktype & AT_FEAR)
961 if (caster->type == PLAYER) 951 if (caster->type == PLAYER)
962 tmp->duration += fear_bonus[caster->stats.Cha]; 952 tmp->duration += fear_bonus[caster->stats.Cha];
963 else 953 else
964 tmp->duration += caster->level / 3; 954 tmp->duration += caster->level / 3;
965 } 955 }
956
966 if (tmp->attacktype & (AT_HOLYWORD | AT_TURN_UNDEAD)) 957 if (tmp->attacktype & (AT_HOLYWORD | AT_TURN_UNDEAD))
967 { 958 {
968 if (caster->type == PLAYER) 959 if (caster->type == PLAYER)
969 tmp->duration += turn_bonus[caster->stats.Wis] / 5; 960 tmp->duration += turn_bonus[caster->stats.Wis] / 5;
970 else 961 else
971 tmp->duration += caster->level / 3; 962 tmp->duration += caster->level / 3;
972 } 963 }
973 964
974
975 if (!(tmp->move_type & MOVE_FLY_LOW)) 965 if (!(tmp->move_type & MOVE_FLY_LOW))
976 LOG (llevDebug, "cast_cone(): arch %s doesn't have flying 1\n", &spell->other_arch->name); 966 LOG (llevDebug, "cast_cone(): arch %s doesn't have flying 1\n", &spell->other_arch->name);
977 967
978 if (!tmp->move_on && tmp->stats.dam) 968 if (!tmp->move_on && tmp->stats.dam)
979 { 969 {
980 LOG (llevDebug, "cast_cone(): arch %s doesn't have move_on set\n", &spell->other_arch->name); 970 LOG (llevDebug, "cast_cone(): arch %s doesn't have move_on set\n", &spell->other_arch->name);
981 } 971 }
972
982 insert_ob_in_map (tmp, m, op, 0); 973 insert_ob_in_map (tmp, m, op, 0);
983 974
984 /* This is used for tracking spells so that one effect doesn't hit 975 /* This is used for tracking spells so that one effect doesn't hit
985 * a single space too many times. 976 * a single space too many times.
986 */ 977 */
987 tmp->stats.maxhp = tmp->count; 978 tmp->stats.maxhp = tmp->count;
988 979
989 if (tmp->other_arch) 980 if (tmp->other_arch)
990 cone_drop (tmp); 981 cone_drop (tmp);
991 } 982 }
983
992 return success; 984 return success;
993} 985}
994 986
995/**************************************************************************** 987/****************************************************************************
996 * 988 *
1010 archetype *at; 1002 archetype *at;
1011 1003
1012 if (op->state != NUM_ANIMATIONS (op) - 1) 1004 if (op->state != NUM_ANIMATIONS (op) - 1)
1013 return; 1005 return;
1014 1006
1015
1016 env = object_get_env_recursive (op); 1007 env = object_get_env_recursive (op);
1017 1008
1018 if (op->env) 1009 if (op->env)
1019 { 1010 {
1020 if (env->map == NULL) 1011 if (env->map == NULL)
1042 1033
1043 /* This copies a lot of the code from the fire bullet, 1034 /* This copies a lot of the code from the fire bullet,
1044 * but using the cast_bullet isn't really feasible, 1035 * but using the cast_bullet isn't really feasible,
1045 * so just set up the appropriate values. 1036 * so just set up the appropriate values.
1046 */ 1037 */
1047 at = find_archetype (SPLINT); 1038 at = archetype::find (SPLINT);
1048 if (at) 1039 if (at)
1049 { 1040 {
1050 for (i = 1; i < 9; i++) 1041 for (i = 1; i < 9; i++)
1051 { 1042 {
1052 if (out_of_map (op->map, op->x + freearr_x[i], op->y + freearr_x[i])) 1043 if (out_of_map (op->map, op->x + freearr_x[i], op->y + freearr_x[i]))
1304 1295
1305 mflags = get_map_flags (op->map, &m, new_x, new_y, &new_x, &new_y); 1296 mflags = get_map_flags (op->map, &m, new_x, new_y, &new_x, &new_y);
1306 1297
1307 if (!(mflags & P_OUT_OF_MAP) && ((mflags & P_IS_ALIVE) || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y)))) 1298 if (!(mflags & P_OUT_OF_MAP) && ((mflags & P_IS_ALIVE) || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))))
1308 { 1299 {
1309 tag_t tag = op->count;
1310
1311 hit_map (op, op->direction, AT_MAGIC, 1); 1300 hit_map (op, op->direction, AT_MAGIC, 1);
1312 /* Basically, missile only hits one thing then goes away. 1301 /* Basically, missile only hits one thing then goes away.
1313 * we need to remove it if someone hasn't already done so. 1302 * we need to remove it if someone hasn't already done so.
1314 */ 1303 */
1315 if (!was_destroyed (op, tag)) 1304 if (!op->destroyed ())
1316 {
1317 remove_ob (op);
1318 free_object (op); 1305 free_object (op);
1319 } 1306
1320 return; 1307 return;
1321 } 1308 }
1322 1309
1323 remove_ob (op); 1310 remove_ob (op);
1311
1324 if (!op->direction || (mflags & P_OUT_OF_MAP)) 1312 if (!op->direction || (mflags & P_OUT_OF_MAP))
1325 { 1313 {
1326 free_object (op); 1314 free_object (op);
1327 return; 1315 return;
1328 } 1316 }
1317
1329 op->x = new_x; 1318 op->x = new_x;
1330 op->y = new_y; 1319 op->y = new_y;
1331 op->map = m; 1320 op->map = m;
1332 i = spell_find_dir (op->map, op->x, op->y, get_owner (op)); 1321 i = spell_find_dir (op->map, op->x, op->y, get_owner (op));
1333 if (i > 0 && i != op->direction) 1322 if (i > 0 && i != op->direction)
1334 { 1323 {
1335 op->direction = i; 1324 op->direction = i;
1336 SET_ANIMATION (op, op->direction); 1325 SET_ANIMATION (op, op->direction);
1337 } 1326 }
1327
1338 insert_ob_in_map (op, op->map, op, 0); 1328 insert_ob_in_map (op, op->map, op, 0);
1339} 1329}
1340 1330
1341/**************************************************************************** 1331/****************************************************************************
1342 * Destruction 1332 * Destruction

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines