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

Comparing deliantra/server/server/attack.C (file contents):
Revision 1.17 by root, Thu Sep 14 22:34:03 2006 UTC vs.
Revision 1.18 by root, Thu Sep 14 23:13:49 2006 UTC

286 object *tmp, *next; 286 object *tmp, *next;
287 mapstruct *map; 287 mapstruct *map;
288 sint16 x, y; 288 sint16 x, y;
289 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */ 289 int retflag = 0; /* added this flag.. will return 1 if it hits a monster */
290 290
291 tag_t op_tag, next_tag = 0;
292
293 if (QUERY_FLAG (op, FLAG_FREED)) 291 if (QUERY_FLAG (op, FLAG_FREED))
294 { 292 {
295 LOG (llevError, "BUG: hit_map(): free object\n"); 293 LOG (llevError, "BUG: hit_map(): free object\n");
296 return 0; 294 return 0;
297 } 295 }
308 return 0; 306 return 0;
309 } 307 }
310 308
311 if (op->head) 309 if (op->head)
312 op = op->head; 310 op = op->head;
313
314 op_tag = op->count;
315 311
316 map = op->map; 312 map = op->map;
317 x = op->x + freearr_x[dir]; 313 x = op->x + freearr_x[dir];
318 y = op->y + freearr_y[dir]; 314 y = op->y + freearr_y[dir];
319 315
347 update_object (op, UP_OBJ_FACE); 343 update_object (op, UP_OBJ_FACE);
348 type &= ~AT_CHAOS; 344 type &= ~AT_CHAOS;
349 } 345 }
350 346
351 next = get_map_ob (map, x, y); 347 next = get_map_ob (map, x, y);
352 if (next)
353 next_tag = next->count;
354 348
355 while (next) 349 while (next)
356 { 350 {
357 if (was_destroyed (next, next_tag)) 351 if (next->destroyed ())
358 { 352 {
359 /* There may still be objects that were above 'next', but there is no 353 /* There may still be objects that were above 'next', but there is no
360 * simple way to find out short of copying all object references and 354 * simple way to find out short of copying all object references and
361 * tags into a temporary array before we start processing the first 355 * tags into a temporary array before we start processing the first
362 * object. That's why we just abort. 356 * object. That's why we just abort.
370 } 364 }
371 365
372 tmp = next; 366 tmp = next;
373 next = tmp->above; 367 next = tmp->above;
374 368
375 if (next) 369 if (tmp->destroyed ())
376 next_tag = next->count;
377
378 if (QUERY_FLAG (tmp, FLAG_FREED))
379 { 370 {
380 LOG (llevError, "BUG: hit_map(): found freed object\n"); 371 LOG (llevError, "BUG: hit_map(): found freed object\n");
381 break; 372 break;
382 } 373 }
383 374
390 381
391 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 382 if (QUERY_FLAG (tmp, FLAG_ALIVE))
392 { 383 {
393 hit_player (tmp, op->stats.dam, op, type, full_hit); 384 hit_player (tmp, op->stats.dam, op, type, full_hit);
394 retflag |= 1; 385 retflag |= 1;
395 if (was_destroyed (op, op_tag)) 386 if (op->destroyed ())
396 break; 387 break;
397 } 388 }
398 389
399 /* Here we are potentially destroying an object. If the object has 390 /* Here we are potentially destroying an object. If the object has
400 * NO_PASS set, it is also immune - you can't destroy walls. Note 391 * NO_PASS set, it is also immune - you can't destroy walls. Note
404 * destroyed right now. 395 * destroyed right now.
405 */ 396 */
406 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block) 397 else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block)
407 { 398 {
408 save_throw_object (tmp, type, op); 399 save_throw_object (tmp, type, op);
409 if (was_destroyed (op, op_tag)) 400 if (op->destroyed ())
410 break; 401 break;
411 } 402 }
412 } 403 }
413 404
414 return 0; 405 return 0;
754attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc) 745attack_ob_simple (object *op, object *hitter, int base_dam, int base_wc)
755{ 746{
756 int simple_attack, roll, dam = 0; 747 int simple_attack, roll, dam = 0;
757 uint32 type; 748 uint32 type;
758 shstr op_name; 749 shstr op_name;
759 tag_t op_tag, hitter_tag;
760 750
761 if (get_attack_mode (&op, &hitter, &simple_attack)) 751 if (get_attack_mode (&op, &hitter, &simple_attack))
762 goto error; 752 goto error;
763 753
764 if (hitter->current_weapon) 754 if (hitter->current_weapon)
765 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op))) 755 if (INVOKE_OBJECT (WEAPON_ATTACK, hitter->current_weapon, ARG_OBJECT (hitter), ARG_OBJECT (op)))
766 return RESULT_INT (0); 756 return RESULT_INT (0);
767 757
768 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter))) 758 if (INVOKE_OBJECT (ATTACK, op, ARG_OBJECT (hitter)))
769 return RESULT_INT (0); 759 return RESULT_INT (0);
770
771 op_tag = op->count;
772 hitter_tag = hitter->count;
773 760
774 /* 761 /*
775 * A little check to make it more difficult to dance forward and back 762 * A little check to make it more difficult to dance forward and back
776 * to avoid ever being hit by monsters. 763 * to avoid ever being hit by monsters.
777 */ 764 */
782 * which then gets here again. By decreasing the speed before 769 * which then gets here again. By decreasing the speed before
783 * we call process_object, the 'if' statement above will fail. 770 * we call process_object, the 'if' statement above will fail.
784 */ 771 */
785 op->speed_left--; 772 op->speed_left--;
786 process_object (op); 773 process_object (op);
787 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 774 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
788 goto error; 775 goto error;
789 } 776 }
790 777
791 op_name = op->name; 778 op_name = op->name;
792 779
843 * when they hit the victim. For things like thrown daggers, 830 * when they hit the victim. For things like thrown daggers,
844 * this sets 'hitter' to the actual dagger, and not the 831 * this sets 'hitter' to the actual dagger, and not the
845 * wrapper object. 832 * wrapper object.
846 */ 833 */
847 thrown_item_effect (hitter, op); 834 thrown_item_effect (hitter, op);
848 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 835 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
849 goto leave; 836 goto leave;
850 } 837 }
851 838
852 /* Need to do at least 1 damage, otherwise there is no point 839 /* Need to do at least 1 damage, otherwise there is no point
853 * to go further and it will cause FPE's below. 840 * to go further and it will cause FPE's below.
854 */ 841 */
855 if (hitdam <= 0) 842 if (hitdam <= 0)
856 hitdam = 1; 843 hitdam = 1;
857 844
858 type = hitter->attacktype; 845 type = hitter->attacktype;
846
859 if (!type) 847 if (!type)
860 type = AT_PHYSICAL; 848 type = AT_PHYSICAL;
849
861 /* Handle monsters that hit back */ 850 /* Handle monsters that hit back */
862 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE)) 851 if (!simple_attack && QUERY_FLAG (op, FLAG_HITBACK) && QUERY_FLAG (hitter, FLAG_ALIVE))
863 { 852 {
864 if (op->attacktype & AT_ACID && hitter->type == PLAYER) 853 if (op->attacktype & AT_ACID && hitter->type == PLAYER)
865 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n"); 854 new_draw_info (NDI_UNIQUE, 0, hitter, "You are splashed by acid!\n");
855
866 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1); 856 hit_player (hitter, random_roll (0, (op->stats.dam), hitter, PREFER_LOW), op, op->attacktype, 1);
857
867 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 858 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
868 goto leave; 859 goto leave;
869 } 860 }
870 861
871 /* In the new attack code, it should handle multiple attack 862 /* In the new attack code, it should handle multiple attack
872 * types in its area, so remove it from here. 863 * types in its area, so remove it from here.
873 */ 864 */
874 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1); 865 dam = hit_player (op, random_roll (1, hitdam, hitter, PREFER_HIGH), hitter, type, 1);
866
875 if (was_destroyed (op, op_tag) || was_destroyed (hitter, hitter_tag) || abort_attack (op, hitter, simple_attack)) 867 if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack))
876 goto leave; 868 goto leave;
877 } /* end of if hitter hit op */ 869 } /* end of if hitter hit op */
878 /* if we missed, dam=0 */ 870 /* if we missed, dam=0 */
879 871
880 /*attack_message(dam, type, op, hitter); */ 872 /*attack_message(dam, type, op, hitter); */
937object * 929object *
938hit_with_arrow (object *op, object *victim) 930hit_with_arrow (object *op, object *victim)
939{ 931{
940 object *container, *hitter; 932 object *container, *hitter;
941 int hit_something = 0; 933 int hit_something = 0;
942 tag_t victim_tag, hitter_tag;
943 sint16 victim_x, victim_y; 934 sint16 victim_x, victim_y;
944 935
945 /* Disassemble missile */ 936 /* Disassemble missile */
946 if (op->inv) 937 if (op->inv)
947 { 938 {
961 } 952 }
962 953
963 /* Try to hit victim */ 954 /* Try to hit victim */
964 victim_x = victim->x; 955 victim_x = victim->x;
965 victim_y = victim->y; 956 victim_y = victim->y;
966 victim_tag = victim->count;
967 hitter_tag = hitter->count;
968 957
969 hit_something = attack_ob_simple (victim, hitter, op->stats.dam, op->stats.wc); 958 hit_something = attack_ob_simple (victim, hitter, op->stats.dam, op->stats.wc);
970 959
971 /* Arrow attacks door, rune of summoning is triggered, demon is put on 960 /* Arrow attacks door, rune of summoning is triggered, demon is put on
972 * arrow, move_apply() calls this function, arrow sticks in demon, 961 * arrow, move_apply() calls this function, arrow sticks in demon,
973 * attack_ob_simple() returns, and we've got an arrow that still exists 962 * attack_ob_simple() returns, and we've got an arrow that still exists
974 * but is no longer on the map. Ugh. (Beware: Such things can happen at 963 * but is no longer on the map. Ugh. (Beware: Such things can happen at
975 * other places as well!) 964 * other places as well!)
976 */ 965 */
977 if (was_destroyed (hitter, hitter_tag) || hitter->env != NULL) 966 if (hitter->destroyed () || hitter->env != NULL)
978 { 967 {
979 if (container) 968 if (container)
980 { 969 {
981 remove_ob (container); 970 remove_ob (container);
982 free_object (container); 971 free_object (container);
1002 remove_ob (container); 991 remove_ob (container);
1003 free_object (container); 992 free_object (container);
1004 } 993 }
1005 994
1006 /* Try to stick arrow into victim */ 995 /* Try to stick arrow into victim */
1007 if (!was_destroyed (victim, victim_tag) && stick_arrow (hitter, victim)) 996 if (!victim->destroyed () && stick_arrow (hitter, victim))
1008 return NULL; 997 return NULL;
1009 998
1010 /* Else try to put arrow on victim's map square 999 /* Else try to put arrow on victim's map square
1011 * remove check for P_WALL here. If the arrow got to this 1000 * remove check for P_WALL here. If the arrow got to this
1012 * space, that is good enough - with the new movement code, 1001 * space, that is good enough - with the new movement code,
1767{ 1756{
1768 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC); 1757 int maxdam = 0, ndam = 0, attacktype = 1, magic = (type & AT_MAGIC);
1769 int maxattacktype, attacknum; 1758 int maxattacktype, attacknum;
1770 int body_attack = op && op->head; /* Did we hit op's head? */ 1759 int body_attack = op && op->head; /* Did we hit op's head? */
1771 int simple_attack; 1760 int simple_attack;
1772 tag_t op_tag, hitter_tag;
1773 int rtn_kill = 0; 1761 int rtn_kill = 0;
1774 int friendlyfire; 1762 int friendlyfire;
1775 1763
1776 if (get_attack_mode (&op, &hitter, &simple_attack)) 1764 if (get_attack_mode (&op, &hitter, &simple_attack))
1777 return 0; 1765 return 0;
1785 { 1773 {
1786 object *owner = get_owner (hitter); 1774 object *owner = get_owner (hitter);
1787 1775
1788 if (!owner) 1776 if (!owner)
1789 owner = hitter; 1777 owner = hitter;
1778
1790 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner) 1779 if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner)
1791 {
1792 return 0; 1780 return 0;
1793 }
1794 } 1781 }
1795#endif 1782#endif
1796
1797 op_tag = op->count;
1798 hitter_tag = hitter->count;
1799 1783
1800 if (body_attack) 1784 if (body_attack)
1801 { 1785 {
1802 /* slow and paralyze must hit the head. But we don't want to just 1786 /* slow and paralyze must hit the head. But we don't want to just
1803 * return - we still need to process other attacks the spell still 1787 * return - we still need to process other attacks the spell still
1809 * attack so we don't cancel out things like magic bullet. 1793 * attack so we don't cancel out things like magic bullet.
1810 */ 1794 */
1811 if (type & (AT_PARALYZE | AT_SLOW)) 1795 if (type & (AT_PARALYZE | AT_SLOW))
1812 { 1796 {
1813 type &= ~(AT_PARALYZE | AT_SLOW); 1797 type &= ~(AT_PARALYZE | AT_SLOW);
1798
1814 if (!type || type == AT_MAGIC) 1799 if (!type || type == AT_MAGIC)
1815 return 0; 1800 return 0;
1816 } 1801 }
1817 } 1802 }
1818 1803
1822 1807
1823 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 1808 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
1824 if (tmp->type == RUNE || tmp->type == TRAP) 1809 if (tmp->type == RUNE || tmp->type == TRAP)
1825 { 1810 {
1826 spring_trap (tmp, hitter); 1811 spring_trap (tmp, hitter);
1827 if (was_destroyed (hitter, hitter_tag) || was_destroyed (op, op_tag) || abort_attack (op, hitter, simple_attack)) 1812 if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack))
1828 return 0; 1813 return 0;
1829 break; 1814 break;
1830 } 1815 }
1831 } 1816 }
1832 1817
1833 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) 1818 if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0)
1834 { 1819 {
1835 /* FIXME: If a player is killed by a rune in a door, the 1820 /* FIXME: If a player is killed by a rune in a door, the
1836 * was_destroyed() check above doesn't return, and might get here. 1821 * destroyed() check above doesn't return, and might get here.
1837 */ 1822 */
1838 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name); 1823 LOG (llevDebug, "victim (arch %s, name %s) already dead in " "hit_player()\n", &op->arch->name, &op->name);
1839 return 0; 1824 return 0;
1840 } 1825 }
1841 1826

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines