… | |
… | |
72 | esrv_send_item (op->env, op); |
72 | esrv_send_item (op->env, op); |
73 | } |
73 | } |
74 | } |
74 | } |
75 | } |
75 | } |
76 | |
76 | |
77 | |
|
|
78 | |
|
|
79 | /* did_make_save_item just checks to make sure the item actually |
77 | /* did_make_save_item just checks to make sure the item actually |
80 | * made its saving throw based on the tables. It does not take |
78 | * made its saving throw based on the tables. It does not take |
81 | * any further action (like destroying the item). |
79 | * any further action (like destroying the item). |
82 | */ |
80 | */ |
83 | |
|
|
84 | int |
81 | int |
85 | did_make_save_item (object *op, int type, object *originator) |
82 | did_make_save_item (object *op, int type, object *originator) |
86 | { |
83 | { |
87 | int i, roll, saves = 0, attacks = 0, number; |
84 | int i, roll, saves = 0, attacks = 0, number; |
88 | materialtype_t *mt; |
85 | materialtype_t *mt; |
89 | |
86 | |
90 | if (op->materialname == NULL) |
87 | if (op->materialname == NULL) |
91 | { |
88 | { |
92 | for (mt = materialt; mt != NULL && mt->next != NULL; mt = mt->next) |
89 | for (mt = materialt; mt != NULL && mt->next != NULL; mt = mt->next) |
93 | { |
|
|
94 | if (op->material & mt->material) |
90 | if (op->material & mt->material) |
95 | break; |
91 | break; |
96 | } |
|
|
97 | } |
92 | } |
98 | else |
93 | else |
99 | mt = name_to_material (op->materialname); |
94 | mt = name_to_material (op->materialname); |
100 | if (mt == NULL) |
95 | if (mt == NULL) |
101 | return TRUE; |
96 | return TRUE; |
… | |
… | |
218 | |
213 | |
219 | if (tmp) |
214 | if (tmp) |
220 | esrv_del_item (tmp->contr, op->count); |
215 | esrv_del_item (tmp->contr, op->count); |
221 | } |
216 | } |
222 | |
217 | |
223 | if (!QUERY_FLAG (op, FLAG_REMOVED)) |
218 | op->destroy (); |
224 | remove_ob (op); |
|
|
225 | |
|
|
226 | free_object (op); |
|
|
227 | } |
219 | } |
228 | |
220 | |
229 | if (type & (AT_FIRE | AT_ELECTRICITY)) |
221 | if (type & (AT_FIRE | AT_ELECTRICITY)) |
230 | if (env) |
222 | if (env) |
231 | { |
223 | { |
… | |
… | |
264 | tmp->move_slow = 0; |
256 | tmp->move_slow = 0; |
265 | insert_ob_in_map (tmp, op->map, originator, 0); |
257 | insert_ob_in_map (tmp, op->map, originator, 0); |
266 | } |
258 | } |
267 | |
259 | |
268 | if (!QUERY_FLAG (op, FLAG_REMOVED)) |
260 | if (!QUERY_FLAG (op, FLAG_REMOVED)) |
269 | remove_ob (op); |
261 | op->remove (); |
270 | |
262 | |
271 | insert_ob_in_ob (op, tmp); |
263 | insert_ob_in_ob (op, tmp); |
272 | return; |
264 | return; |
273 | } |
265 | } |
274 | } |
266 | } |
… | |
… | |
435 | sprintf (buf1, "missed %s", &op->name); |
427 | sprintf (buf1, "missed %s", &op->name); |
436 | sprintf (buf2, " misses"); |
428 | sprintf (buf2, " misses"); |
437 | found++; |
429 | found++; |
438 | } |
430 | } |
439 | else if ((hitter->type == DISEASE || hitter->type == SYMPTOM || |
431 | else if ((hitter->type == DISEASE || hitter->type == SYMPTOM || |
440 | hitter->type == POISONING || (type & AT_POISON && IS_LIVE (op))) && !found) |
432 | hitter->type == POISONING || (type & AT_POISON && op->is_alive ())) && !found) |
441 | { |
433 | { |
442 | for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_SUFFER][i].level != -1; i++) |
434 | for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_SUFFER][i].level != -1; i++) |
443 | if (dam < attack_mess[ATM_SUFFER][i].level || attack_mess[ATM_SUFFER][i + 1].level == -1) |
435 | if (dam < attack_mess[ATM_SUFFER][i].level || attack_mess[ATM_SUFFER][i + 1].level == -1) |
444 | { |
436 | { |
445 | sprintf (buf1, "%s %s%s", attack_mess[ATM_SUFFER][i].buf1, &op->name, attack_mess[ATM_SUFFER][i].buf2); |
437 | sprintf (buf1, "%s %s%s", attack_mess[ATM_SUFFER][i].buf1, &op->name, attack_mess[ATM_SUFFER][i].buf2); |
… | |
… | |
457 | strcpy (buf2, attack_mess[ATM_DOOR][i].buf3); |
449 | strcpy (buf2, attack_mess[ATM_DOOR][i].buf3); |
458 | found++; |
450 | found++; |
459 | break; |
451 | break; |
460 | } |
452 | } |
461 | } |
453 | } |
462 | else if (hitter->type == PLAYER && IS_LIVE (op)) |
454 | else if (hitter->type == PLAYER && op->is_alive ()) |
463 | { |
455 | { |
464 | if (USING_SKILL (hitter, SK_KARATE)) |
456 | if (USING_SKILL (hitter, SK_KARATE)) |
465 | { |
457 | { |
466 | for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_KARATE][i].level != -1; i++) |
458 | for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_KARATE][i].level != -1; i++) |
467 | if (dam < attack_mess[ATM_KARATE][i].level || attack_mess[ATM_KARATE][i + 1].level == -1) |
459 | if (dam < attack_mess[ATM_KARATE][i].level || attack_mess[ATM_KARATE][i + 1].level == -1) |
… | |
… | |
493 | found++; |
485 | found++; |
494 | break; |
486 | break; |
495 | } |
487 | } |
496 | } |
488 | } |
497 | } |
489 | } |
|
|
490 | |
498 | if (found) |
491 | if (found) |
499 | { |
492 | { |
500 | /* done */ |
493 | /* done */ |
501 | } |
494 | } |
502 | else if (IS_ARROW (hitter) && (type == AT_PHYSICAL || type == AT_MAGIC)) |
495 | else if (hitter->is_arrow () && (type == AT_PHYSICAL || type == AT_MAGIC)) |
503 | { |
496 | { |
504 | sprintf (buf1, "hit"); /* just in case */ |
497 | sprintf (buf1, "hit"); /* just in case */ |
505 | for (i = 0; i < MAXATTACKMESS; i++) |
498 | for (i = 0; i < MAXATTACKMESS; i++) |
506 | if (dam < attack_mess[ATM_ARROW][i].level || attack_mess[ATM_ARROW][i + 1].level == -1) |
499 | if (dam < attack_mess[ATM_ARROW][i].level || attack_mess[ATM_ARROW][i + 1].level == -1) |
507 | { |
500 | { |
508 | strcpy (buf2, attack_mess[ATM_ARROW][i].buf3); |
501 | strcpy (buf2, attack_mess[ATM_ARROW][i].buf3); |
509 | found++; |
502 | found++; |
510 | break; |
503 | break; |
511 | } |
504 | } |
512 | } |
505 | } |
513 | else if (type & AT_DRAIN && IS_LIVE (op)) |
506 | else if (type & AT_DRAIN && op->is_alive ()) |
514 | { |
507 | { |
515 | /* drain is first, because some items have multiple attypes */ |
508 | /* drain is first, because some items have multiple attypes */ |
516 | for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_DRAIN][i].level != -1; i++) |
509 | for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_DRAIN][i].level != -1; i++) |
517 | if (dam < attack_mess[ATM_DRAIN][i].level || attack_mess[ATM_DRAIN][i + 1].level == -1) |
510 | if (dam < attack_mess[ATM_DRAIN][i].level || attack_mess[ATM_DRAIN][i + 1].level == -1) |
518 | { |
511 | { |
… | |
… | |
520 | strcpy (buf2, attack_mess[ATM_DRAIN][i].buf3); |
513 | strcpy (buf2, attack_mess[ATM_DRAIN][i].buf3); |
521 | found++; |
514 | found++; |
522 | break; |
515 | break; |
523 | } |
516 | } |
524 | } |
517 | } |
525 | else if (type & AT_ELECTRICITY && IS_LIVE (op)) |
518 | else if (type & AT_ELECTRICITY && op->is_alive ()) |
526 | { |
519 | { |
527 | for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_ELEC][i].level != -1; i++) |
520 | for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_ELEC][i].level != -1; i++) |
528 | if (dam < attack_mess[ATM_ELEC][i].level || attack_mess[ATM_ELEC][i + 1].level == -1) |
521 | if (dam < attack_mess[ATM_ELEC][i].level || attack_mess[ATM_ELEC][i + 1].level == -1) |
529 | { |
522 | { |
530 | sprintf (buf1, "%s %s%s", attack_mess[ATM_ELEC][i].buf1, &op->name, attack_mess[ATM_ELEC][i].buf2); |
523 | sprintf (buf1, "%s %s%s", attack_mess[ATM_ELEC][i].buf1, &op->name, attack_mess[ATM_ELEC][i].buf2); |
531 | strcpy (buf2, attack_mess[ATM_ELEC][i].buf3); |
524 | strcpy (buf2, attack_mess[ATM_ELEC][i].buf3); |
532 | found++; |
525 | found++; |
533 | break; |
526 | break; |
534 | } |
527 | } |
535 | } |
528 | } |
536 | else if (type & AT_COLD && IS_LIVE (op)) |
529 | else if (type & AT_COLD && op->is_alive ()) |
537 | { |
530 | { |
538 | for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_COLD][i].level != -1; i++) |
531 | for (i = 0; i < MAXATTACKMESS && attack_mess[ATM_COLD][i].level != -1; i++) |
539 | if (dam < attack_mess[ATM_COLD][i].level || attack_mess[ATM_COLD][i + 1].level == -1) |
532 | if (dam < attack_mess[ATM_COLD][i].level || attack_mess[ATM_COLD][i + 1].level == -1) |
540 | { |
533 | { |
541 | sprintf (buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1, &op->name, attack_mess[ATM_COLD][i].buf2); |
534 | sprintf (buf1, "%s %s%s", attack_mess[ATM_COLD][i].buf1, &op->name, attack_mess[ATM_COLD][i].buf2); |
… | |
… | |
618 | strcpy (buf1, "hit"); |
611 | strcpy (buf1, "hit"); |
619 | strcpy (buf2, " hits"); |
612 | strcpy (buf2, " hits"); |
620 | } |
613 | } |
621 | |
614 | |
622 | /* bail out if a monster is casting spells */ |
615 | /* bail out if a monster is casting spells */ |
623 | if (!(hitter->type == PLAYER || (get_owner (hitter) != NULL && hitter->owner->type == PLAYER))) |
616 | if (!(hitter->type == PLAYER || (hitter->owner != NULL && hitter->owner->type == PLAYER))) |
624 | return; |
617 | return; |
625 | |
618 | |
626 | /* scale down magic considerably. */ |
619 | /* scale down magic considerably. */ |
627 | if (type & AT_MAGIC && rndm (0, 5)) |
620 | if (type & AT_MAGIC && rndm (0, 5)) |
628 | return; |
621 | return; |
629 | |
622 | |
630 | /* Did a player hurt another player? Inform both! */ |
623 | /* Did a player hurt another player? Inform both! */ |
631 | if (op->type == PLAYER && (get_owner (hitter) == NULL ? hitter->type : hitter->owner->type) == PLAYER) |
624 | if (op->type == PLAYER && (hitter->owner == NULL ? hitter->type : hitter->owner->type) == PLAYER) |
632 | { |
625 | { |
633 | if (get_owner (hitter) != NULL) |
626 | if (hitter->owner != NULL) |
634 | sprintf (buf, "%s's %s%s you.", &hitter->owner->name, &hitter->name, buf2); |
627 | sprintf (buf, "%s's %s%s you.", &hitter->owner->name, &hitter->name, buf2); |
635 | else |
628 | else |
636 | { |
629 | { |
637 | sprintf (buf, "%s%s you.", &hitter->name, buf2); |
630 | sprintf (buf, "%s%s you.", &hitter->name, buf2); |
638 | if (dam != 0) |
631 | if (dam != 0) |
… | |
… | |
660 | else |
653 | else |
661 | play_sound_player_only (hitter->contr, SOUND_PLAYER_HITS3, 0, 0); |
654 | play_sound_player_only (hitter->contr, SOUND_PLAYER_HITS3, 0, 0); |
662 | } |
655 | } |
663 | new_draw_info (NDI_BLACK, 0, hitter, buf); |
656 | new_draw_info (NDI_BLACK, 0, hitter, buf); |
664 | } |
657 | } |
665 | else if (get_owner (hitter) != NULL && hitter->owner->type == PLAYER) |
658 | else if (hitter->owner != NULL && hitter->owner->type == PLAYER) |
666 | { |
659 | { |
667 | /* look for stacked spells and start reducing the message chances */ |
660 | /* look for stacked spells and start reducing the message chances */ |
668 | if (hitter->type == SPELL_EFFECT && (hitter->subtype == SP_EXPLOSION || hitter->subtype == SP_BULLET || hitter->subtype == SP_CONE)) |
661 | if (hitter->type == SPELL_EFFECT && (hitter->subtype == SP_EXPLOSION || hitter->subtype == SP_BULLET || hitter->subtype == SP_CONE)) |
669 | { |
662 | { |
670 | i = 4; |
663 | i = 4; |
… | |
… | |
769 | * which then gets here again. By decreasing the speed before |
762 | * which then gets here again. By decreasing the speed before |
770 | * we call process_object, the 'if' statement above will fail. |
763 | * we call process_object, the 'if' statement above will fail. |
771 | */ |
764 | */ |
772 | op->speed_left--; |
765 | op->speed_left--; |
773 | process_object (op); |
766 | process_object (op); |
|
|
767 | |
774 | if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack)) |
768 | if (op->destroyed () || hitter->destroyed () || abort_attack (op, hitter, simple_attack)) |
775 | goto error; |
769 | goto error; |
776 | } |
770 | } |
777 | |
771 | |
778 | op_name = op->name; |
772 | op_name = op->name; |
… | |
… | |
813 | if (QUERY_FLAG (op, FLAG_SLEEP)) |
807 | if (QUERY_FLAG (op, FLAG_SLEEP)) |
814 | CLEAR_FLAG (op, FLAG_SLEEP); |
808 | CLEAR_FLAG (op, FLAG_SLEEP); |
815 | |
809 | |
816 | /* If the victim can't see the attacker, it may alert others |
810 | /* If the victim can't see the attacker, it may alert others |
817 | * for help. */ |
811 | * for help. */ |
818 | if (op->type != PLAYER && !can_see_enemy (op, hitter) && !get_owner (op) && rndm (0, op->stats.Int)) |
812 | if (op->type != PLAYER && !can_see_enemy (op, hitter) && !op->owner && rndm (0, op->stats.Int)) |
819 | npc_call_help (op); |
813 | npc_call_help (op); |
820 | |
814 | |
821 | /* if you were hidden and hit by a creature, you are discovered */ |
815 | /* if you were hidden and hit by a creature, you are discovered */ |
822 | if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE)) |
816 | if (op->hide && QUERY_FLAG (hitter, FLAG_ALIVE)) |
823 | { |
817 | { |
… | |
… | |
830 | * when they hit the victim. For things like thrown daggers, |
824 | * when they hit the victim. For things like thrown daggers, |
831 | * this sets 'hitter' to the actual dagger, and not the |
825 | * this sets 'hitter' to the actual dagger, and not the |
832 | * wrapper object. |
826 | * wrapper object. |
833 | */ |
827 | */ |
834 | thrown_item_effect (hitter, op); |
828 | thrown_item_effect (hitter, op); |
|
|
829 | |
835 | if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack)) |
830 | if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack)) |
836 | goto leave; |
831 | goto leave; |
837 | } |
832 | } |
838 | |
833 | |
839 | /* Need to do at least 1 damage, otherwise there is no point |
834 | /* Need to do at least 1 damage, otherwise there is no point |
… | |
… | |
906 | if (op->weight <= 5000 && tmp->stats.hp >= 0) |
901 | if (op->weight <= 5000 && tmp->stats.hp >= 0) |
907 | { |
902 | { |
908 | if (tmp->head != NULL) |
903 | if (tmp->head != NULL) |
909 | tmp = tmp->head; |
904 | tmp = tmp->head; |
910 | |
905 | |
911 | remove_ob (op); |
906 | op->remove (); |
912 | op = insert_ob_in_ob (op, tmp); |
907 | op = insert_ob_in_ob (op, tmp); |
913 | |
908 | |
914 | if (tmp->type == PLAYER) |
909 | if (tmp->type == PLAYER) |
915 | esrv_send_item (tmp, op); |
910 | esrv_send_item (tmp, op); |
916 | |
911 | |
… | |
… | |
935 | /* Disassemble missile */ |
930 | /* Disassemble missile */ |
936 | if (op->inv) |
931 | if (op->inv) |
937 | { |
932 | { |
938 | container = op; |
933 | container = op; |
939 | hitter = op->inv; |
934 | hitter = op->inv; |
940 | remove_ob (hitter); |
935 | hitter->remove (); |
941 | insert_ob_in_map (hitter, container->map, hitter, INS_NO_MERGE | INS_NO_WALK_ON); |
936 | insert_ob_in_map (hitter, container->map, hitter, INS_NO_MERGE | INS_NO_WALK_ON); |
942 | /* Note that we now have an empty THROWN_OBJ on the map. Code that |
937 | /* Note that we now have an empty THROWN_OBJ on the map. Code that |
943 | * might be called until this THROWN_OBJ is either reassembled or |
938 | * might be called until this THROWN_OBJ is either reassembled or |
944 | * removed at the end of this function must be able to deal with empty |
939 | * removed at the end of this function must be able to deal with empty |
945 | * THROWN_OBJs. */ |
940 | * THROWN_OBJs. */ |
… | |
… | |
961 | */ |
956 | */ |
962 | if (hitter->destroyed () || hitter->env != NULL) |
957 | if (hitter->destroyed () || hitter->env != NULL) |
963 | { |
958 | { |
964 | if (container) |
959 | if (container) |
965 | { |
960 | { |
966 | remove_ob (container); |
961 | container->remove (); |
967 | free_object (container); |
962 | container->destroy (); |
968 | } |
963 | } |
969 | |
964 | |
970 | return 0; |
965 | return 0; |
971 | } |
966 | } |
972 | |
967 | |
… | |
… | |
982 | hitter = fix_stopped_arrow (hitter); |
977 | hitter = fix_stopped_arrow (hitter); |
983 | if (!hitter) |
978 | if (!hitter) |
984 | return 0; |
979 | return 0; |
985 | } |
980 | } |
986 | else |
981 | else |
987 | { |
982 | container->destroy (); |
988 | remove_ob (container); |
|
|
989 | free_object (container); |
|
|
990 | } |
|
|
991 | |
983 | |
992 | /* Try to stick arrow into victim */ |
984 | /* Try to stick arrow into victim */ |
993 | if (!victim->destroyed () && stick_arrow (hitter, victim)) |
985 | if (!victim->destroyed () && stick_arrow (hitter, victim)) |
994 | return 0; |
986 | return 0; |
995 | |
987 | |
… | |
… | |
1000 | * can fly over but not otherwise move over. What is the correct |
992 | * can fly over but not otherwise move over. What is the correct |
1001 | * way to handle those otherwise? |
993 | * way to handle those otherwise? |
1002 | */ |
994 | */ |
1003 | if (victim->x != hitter->x || victim->y != hitter->y) |
995 | if (victim->x != hitter->x || victim->y != hitter->y) |
1004 | { |
996 | { |
1005 | remove_ob (hitter); |
997 | hitter->remove (); |
1006 | hitter->x = victim->x; |
998 | hitter->x = victim->x; |
1007 | hitter->y = victim->y; |
999 | hitter->y = victim->y; |
1008 | insert_ob_in_map (hitter, victim->map, hitter, 0); |
1000 | insert_ob_in_map (hitter, victim->map, hitter, 0); |
1009 | } |
1001 | } |
1010 | else |
1002 | else |
… | |
… | |
1018 | op->speed -= 1.0; |
1010 | op->speed -= 1.0; |
1019 | |
1011 | |
1020 | /* Missile missed victim - reassemble missile */ |
1012 | /* Missile missed victim - reassemble missile */ |
1021 | if (container) |
1013 | if (container) |
1022 | { |
1014 | { |
1023 | remove_ob (hitter); |
1015 | hitter->remove (); |
1024 | insert_ob_in_ob (hitter, container); |
1016 | insert_ob_in_ob (hitter, container); |
1025 | } |
1017 | } |
1026 | |
1018 | |
1027 | return op; |
1019 | return op; |
1028 | } |
1020 | } |
… | |
… | |
1040 | } |
1032 | } |
1041 | else if (!GET_ANIM_ID (op)) |
1033 | else if (!GET_ANIM_ID (op)) |
1042 | { |
1034 | { |
1043 | /* Object has been called - no animations, so remove it */ |
1035 | /* Object has been called - no animations, so remove it */ |
1044 | if (op->stats.hp < 0) |
1036 | if (op->stats.hp < 0) |
|
|
1037 | op->destroy (); |
1045 | { |
1038 | |
1046 | remove_ob (op); /* Should update LOS */ |
|
|
1047 | free_object (op); |
|
|
1048 | /* Don't know why this is here - remove_ob should do it for us */ |
|
|
1049 | /*update_position(m, x, y); */ |
|
|
1050 | } |
|
|
1051 | return; /* no animations, so nothing more to do */ |
1039 | return; /* no animations, so nothing more to do */ |
1052 | } |
1040 | } |
|
|
1041 | |
1053 | perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp; |
1042 | perc = NUM_ANIMATIONS (op) - ((int) NUM_ANIMATIONS (op) * op->stats.hp) / op->stats.maxhp; |
|
|
1043 | |
1054 | if (perc >= (int) NUM_ANIMATIONS (op)) |
1044 | if (perc >= (int) NUM_ANIMATIONS (op)) |
1055 | perc = NUM_ANIMATIONS (op) - 1; |
1045 | perc = NUM_ANIMATIONS (op) - 1; |
1056 | else if (perc < 1) |
1046 | else if (perc < 1) |
1057 | perc = 1; |
1047 | perc = 1; |
|
|
1048 | |
1058 | SET_ANIMATION (op, perc); |
1049 | SET_ANIMATION (op, perc); |
1059 | update_object (op, UP_OBJ_FACE); |
1050 | update_object (op, UP_OBJ_FACE); |
|
|
1051 | |
1060 | if (perc == NUM_ANIMATIONS (op) - 1) |
1052 | if (perc == NUM_ANIMATIONS (op) - 1) |
1061 | { /* Reached the last animation */ |
1053 | { /* Reached the last animation */ |
1062 | if (op->face == blank_face) |
1054 | if (op->face == blank_face) |
1063 | { |
|
|
1064 | /* If the last face is blank, remove the ob */ |
1055 | /* If the last face is blank, remove the ob */ |
1065 | remove_ob (op); /* Should update LOS */ |
1056 | op->destroy (); |
1066 | free_object (op); |
|
|
1067 | |
|
|
1068 | /* remove_ob should call update_position for us */ |
|
|
1069 | /*update_position(m, x, y); */ |
|
|
1070 | |
|
|
1071 | } |
|
|
1072 | else |
1057 | else |
1073 | { /* The last face was not blank, leave an image */ |
1058 | { /* The last face was not blank, leave an image */ |
1074 | CLEAR_FLAG (op, FLAG_BLOCKSVIEW); |
1059 | CLEAR_FLAG (op, FLAG_BLOCKSVIEW); |
1075 | update_all_los (op->map, op->x, op->y); |
1060 | update_all_los (op->map, op->x, op->y); |
1076 | op->move_block = 0; |
1061 | op->move_block = 0; |
… | |
… | |
1080 | } |
1065 | } |
1081 | |
1066 | |
1082 | void |
1067 | void |
1083 | scare_creature (object *target, object *hitter) |
1068 | scare_creature (object *target, object *hitter) |
1084 | { |
1069 | { |
1085 | object *owner = get_owner (hitter); |
1070 | object *owner = hitter->owner; |
1086 | |
1071 | |
1087 | if (!owner) |
1072 | if (!owner) |
1088 | owner = hitter; |
1073 | owner = hitter; |
1089 | |
1074 | |
1090 | SET_FLAG (target, FLAG_SCARED); |
1075 | SET_FLAG (target, FLAG_SCARED); |
… | |
… | |
1294 | * Try to credit the owner. We try to display player -> player drain |
1279 | * Try to credit the owner. We try to display player -> player drain |
1295 | * attacks, hence all the != PLAYER checks. |
1280 | * attacks, hence all the != PLAYER checks. |
1296 | */ |
1281 | */ |
1297 | if (!op_on_battleground (hitter, NULL, NULL) && !QUERY_FLAG (op, FLAG_WAS_WIZ)) |
1282 | if (!op_on_battleground (hitter, NULL, NULL) && !QUERY_FLAG (op, FLAG_WAS_WIZ)) |
1298 | { |
1283 | { |
1299 | object *owner = get_owner (hitter); |
1284 | object *owner = hitter->owner; |
1300 | |
1285 | |
1301 | if (owner && owner != hitter) |
1286 | if (owner && owner != hitter) |
1302 | { |
1287 | { |
1303 | if (op->type != PLAYER || owner->type != PLAYER) |
1288 | if (op->type != PLAYER || owner->type != PLAYER) |
1304 | change_exp (owner, op->stats.exp / (rate * 2), |
1289 | change_exp (owner, op->stats.exp / (rate * 2), |
… | |
… | |
1451 | |
1436 | |
1452 | if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER) |
1437 | if (QUERY_FLAG (op, FLAG_FRIENDLY) && op->type != PLAYER) |
1453 | { |
1438 | { |
1454 | remove_friendly_object (op); |
1439 | remove_friendly_object (op); |
1455 | |
1440 | |
1456 | if (get_owner (op) && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op) |
1441 | if (op->owner && op->owner->type == PLAYER && op->owner->contr->ranges[range_golem] == op) |
1457 | op->owner->contr->ranges[range_golem] = 0; |
1442 | op->owner->contr->ranges[range_golem] = 0; |
1458 | |
1443 | |
1459 | remove_ob (op); |
1444 | op->destroy (); |
1460 | free_object (op); |
|
|
1461 | return maxdam; |
1445 | return maxdam; |
1462 | } |
1446 | } |
1463 | |
1447 | |
1464 | /* Now lets start dealing with experience we get for killing something */ |
1448 | /* Now lets start dealing with experience we get for killing something */ |
1465 | |
1449 | |
1466 | owner = get_owner (hitter); |
1450 | owner = hitter->owner; |
1467 | if (!owner) |
1451 | if (!owner) |
1468 | owner = hitter; |
1452 | owner = hitter; |
1469 | |
1453 | |
1470 | /* is the victim (op) standing on battleground? */ |
1454 | /* is the victim (op) standing on battleground? */ |
1471 | if (op_on_battleground (op, NULL, NULL)) |
1455 | if (op_on_battleground (op, NULL, NULL)) |
… | |
… | |
1492 | char buf[256]; |
1476 | char buf[256]; |
1493 | |
1477 | |
1494 | tmv = localtime (&t); |
1478 | tmv = localtime (&t); |
1495 | strftime (buf, 256, "%a %b %d %H:%M:%S %Y", tmv); |
1479 | strftime (buf, 256, "%a %b %d %H:%M:%S %Y", tmv); |
1496 | |
1480 | |
1497 | LOG (llevInfo, "%s PLAYER_KILL_PLAYER: %s (%s) killed %s\n", buf, &owner->name, owner->contr->socket.host, query_name (op)); |
1481 | LOG (llevInfo, "%s PLAYER_KILL_PLAYER: %s (%s) killed %s\n", buf, &owner->name, owner->contr->socket->host, query_name (op)); |
1498 | } |
1482 | } |
1499 | |
1483 | |
1500 | /* try to filter some things out - basically, if you are |
1484 | /* try to filter some things out - basically, if you are |
1501 | * killing a level 1 creature and your level 20, you |
1485 | * killing a level 1 creature and your level 20, you |
1502 | * probably don't want to see that. |
1486 | * probably don't want to see that. |
… | |
… | |
1652 | |
1636 | |
1653 | if (op->type != PLAYER) |
1637 | if (op->type != PLAYER) |
1654 | { |
1638 | { |
1655 | if (QUERY_FLAG (op, FLAG_FRIENDLY)) |
1639 | if (QUERY_FLAG (op, FLAG_FRIENDLY)) |
1656 | { |
1640 | { |
1657 | object *owner1 = get_owner (op); |
1641 | object *owner1 = op->owner; |
1658 | |
1642 | |
1659 | if (owner1 && owner1->type == PLAYER) |
1643 | if (owner1 && owner1->type == PLAYER) |
1660 | { |
1644 | { |
1661 | play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0); |
1645 | play_sound_player_only (owner1->contr, SOUND_PET_IS_KILLED, 0, 0); |
1662 | /* Maybe we should include the owner that killed this, maybe not */ |
1646 | /* Maybe we should include the owner that killed this, maybe not */ |
… | |
… | |
1664 | } |
1648 | } |
1665 | |
1649 | |
1666 | remove_friendly_object (op); |
1650 | remove_friendly_object (op); |
1667 | } |
1651 | } |
1668 | |
1652 | |
1669 | remove_ob (op); |
1653 | op->destroy (); |
1670 | free_object (op); |
|
|
1671 | } |
1654 | } |
1672 | else |
1655 | else |
1673 | { |
1656 | { |
1674 | /* Player has been killed! */ |
1657 | /* Player has been killed! */ |
1675 | if (owner->type == PLAYER) |
1658 | if (owner->type == PLAYER) |
… | |
… | |
1705 | return 0; |
1688 | return 0; |
1706 | |
1689 | |
1707 | if (hitter->type == PLAYER && hitter->contr->peaceful == 1) |
1690 | if (hitter->type == PLAYER && hitter->contr->peaceful == 1) |
1708 | return 1; |
1691 | return 1; |
1709 | |
1692 | |
1710 | if ((owner = get_owner (hitter)) != NULL) |
1693 | if ((owner = hitter->owner) != NULL) |
1711 | { |
1694 | { |
1712 | if (owner->type == PLAYER && owner->contr->peaceful == 1) |
1695 | if (owner->type == PLAYER && owner->contr->peaceful == 1) |
1713 | friendlyfire = 2; |
1696 | friendlyfire = 2; |
1714 | } |
1697 | } |
1715 | |
1698 | |
… | |
… | |
1749 | return 0; |
1732 | return 0; |
1750 | |
1733 | |
1751 | #ifdef PROHIBIT_PLAYERKILL |
1734 | #ifdef PROHIBIT_PLAYERKILL |
1752 | if (op->type == PLAYER) |
1735 | if (op->type == PLAYER) |
1753 | { |
1736 | { |
1754 | object *owner = get_owner (hitter); |
1737 | object *owner = hitter->owner; |
1755 | |
1738 | |
1756 | if (!owner) |
1739 | if (!owner) |
1757 | owner = hitter; |
1740 | owner = hitter; |
1758 | |
1741 | |
1759 | if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner) |
1742 | if (owner->type == PLAYER && (!op_on_battleground (op, 0, 0) && (op->contr->peaceful || owner->contr->peaceful)) && op != owner) |
… | |
… | |
1787 | |
1770 | |
1788 | for (tmp = op->inv; tmp != NULL; tmp = tmp->below) |
1771 | for (tmp = op->inv; tmp != NULL; tmp = tmp->below) |
1789 | if (tmp->type == RUNE || tmp->type == TRAP) |
1772 | if (tmp->type == RUNE || tmp->type == TRAP) |
1790 | { |
1773 | { |
1791 | spring_trap (tmp, hitter); |
1774 | spring_trap (tmp, hitter); |
|
|
1775 | |
1792 | if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack)) |
1776 | if (hitter->destroyed () || op->destroyed () || abort_attack (op, hitter, simple_attack)) |
1793 | return 0; |
1777 | return 0; |
|
|
1778 | |
1794 | break; |
1779 | break; |
1795 | } |
1780 | } |
1796 | } |
1781 | } |
1797 | |
1782 | |
1798 | if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) |
1783 | if (!QUERY_FLAG (op, FLAG_ALIVE) || op->stats.hp < 0) |
… | |
… | |
1915 | |
1900 | |
1916 | #ifdef ATTACK_DEBUG |
1901 | #ifdef ATTACK_DEBUG |
1917 | LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam); |
1902 | LOG (llevDebug, "Attacktype %d did %d damage\n", type, maxdam); |
1918 | #endif |
1903 | #endif |
1919 | |
1904 | |
1920 | if (get_owner (hitter)) |
1905 | if (hitter->owner) |
1921 | op->enemy = hitter->owner; |
1906 | op->enemy = hitter->owner; |
1922 | else if (QUERY_FLAG (hitter, FLAG_ALIVE)) |
1907 | else if (QUERY_FLAG (hitter, FLAG_ALIVE)) |
1923 | op->enemy = hitter; |
1908 | op->enemy = hitter; |
1924 | |
1909 | |
1925 | if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER) |
1910 | if (QUERY_FLAG (op, FLAG_UNAGGRESSIVE) && op->type != PLAYER) |
… | |
… | |
1950 | |
1935 | |
1951 | if (QUERY_FLAG (op, FLAG_TEAR_DOWN)) |
1936 | if (QUERY_FLAG (op, FLAG_TEAR_DOWN)) |
1952 | { |
1937 | { |
1953 | if (maxdam) |
1938 | if (maxdam) |
1954 | tear_down_wall (op); |
1939 | tear_down_wall (op); |
|
|
1940 | |
1955 | return maxdam; /* nothing more to do for wall */ |
1941 | return maxdam; /* nothing more to do for wall */ |
1956 | } |
1942 | } |
1957 | |
1943 | |
1958 | /* See if the creature has been killed */ |
1944 | /* See if the creature has been killed */ |
1959 | rtn_kill = kill_object (op, maxdam, hitter, type); |
1945 | rtn_kill = kill_object (op, maxdam, hitter, type); |
… | |
… | |
1967 | */ |
1953 | */ |
1968 | if (QUERY_FLAG (hitter, FLAG_ONE_HIT)) |
1954 | if (QUERY_FLAG (hitter, FLAG_ONE_HIT)) |
1969 | { |
1955 | { |
1970 | if (QUERY_FLAG (hitter, FLAG_FRIENDLY)) |
1956 | if (QUERY_FLAG (hitter, FLAG_FRIENDLY)) |
1971 | remove_friendly_object (hitter); |
1957 | remove_friendly_object (hitter); |
1972 | remove_ob (hitter); |
1958 | |
1973 | free_object (hitter); |
1959 | hitter->destroy (); |
1974 | } |
1960 | } |
1975 | /* Lets handle creatures that are splitting now */ |
1961 | /* Lets handle creatures that are splitting now */ |
1976 | else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING)) |
1962 | else if (type & AT_PHYSICAL && !QUERY_FLAG (op, FLAG_FREED) && QUERY_FLAG (op, FLAG_SPLITTING)) |
1977 | { |
1963 | { |
1978 | int i; |
1964 | int i; |
1979 | int friendly = QUERY_FLAG (op, FLAG_FRIENDLY); |
1965 | int friendly = QUERY_FLAG (op, FLAG_FRIENDLY); |
1980 | int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE); |
1966 | int unaggressive = QUERY_FLAG (op, FLAG_UNAGGRESSIVE); |
1981 | object *owner = get_owner (op); |
1967 | object *owner = op->owner; |
1982 | |
1968 | |
1983 | if (!op->other_arch) |
1969 | if (!op->other_arch) |
1984 | { |
1970 | { |
1985 | LOG (llevError, "SPLITTING without other_arch error.\n"); |
1971 | LOG (llevError, "SPLITTING without other_arch error.\n"); |
1986 | return maxdam; |
1972 | return maxdam; |
1987 | } |
1973 | } |
|
|
1974 | |
1988 | remove_ob (op); |
1975 | op->remove (); |
|
|
1976 | |
1989 | for (i = 0; i < NROFNEWOBJS (op); i++) |
1977 | for (i = 0; i < NROFNEWOBJS (op); i++) |
1990 | { /* This doesn't handle op->more yet */ |
1978 | { /* This doesn't handle op->more yet */ |
1991 | object *tmp = arch_to_object (op->other_arch); |
1979 | object *tmp = arch_to_object (op->other_arch); |
1992 | int j; |
1980 | int j; |
1993 | |
1981 | |
1994 | tmp->stats.hp = op->stats.hp; |
1982 | tmp->stats.hp = op->stats.hp; |
|
|
1983 | |
1995 | if (friendly) |
1984 | if (friendly) |
1996 | { |
1985 | { |
1997 | SET_FLAG (tmp, FLAG_FRIENDLY); |
1986 | SET_FLAG (tmp, FLAG_FRIENDLY); |
1998 | add_friendly_object (tmp); |
1987 | add_friendly_object (tmp); |
1999 | tmp->attack_movement = PETMOVE; |
1988 | tmp->attack_movement = PETMOVE; |
2000 | if (owner != NULL) |
1989 | if (owner != NULL) |
2001 | set_owner (tmp, owner); |
1990 | tmp->set_owner (owner); |
2002 | } |
1991 | } |
|
|
1992 | |
2003 | if (unaggressive) |
1993 | if (unaggressive) |
2004 | SET_FLAG (tmp, FLAG_UNAGGRESSIVE); |
1994 | SET_FLAG (tmp, FLAG_UNAGGRESSIVE); |
|
|
1995 | |
2005 | j = find_first_free_spot (tmp, op->map, op->x, op->y); |
1996 | j = find_first_free_spot (tmp, op->map, op->x, op->y); |
|
|
1997 | |
2006 | if (j == -1) /* No spot to put this monster */ |
1998 | if (j == -1) /* No spot to put this monster */ |
2007 | free_object (tmp); |
1999 | tmp->destroy (); |
2008 | else |
2000 | else |
2009 | { |
2001 | { |
2010 | tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j]; |
2002 | tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j]; |
2011 | insert_ob_in_map (tmp, op->map, NULL, 0); |
2003 | insert_ob_in_map (tmp, op->map, NULL, 0); |
2012 | } |
2004 | } |
2013 | } |
2005 | } |
2014 | if (friendly) |
2006 | |
2015 | remove_friendly_object (op); |
2007 | op->destroy (); |
2016 | free_object (op); |
|
|
2017 | } |
2008 | } |
2018 | else if (type & AT_DRAIN && hitter->type == GRIMREAPER && hitter->value++ > 10) |
2009 | else if (type & AT_DRAIN && hitter->type == GRIMREAPER && hitter->value++ > 10) |
2019 | { |
2010 | hitter->destroy (); |
2020 | remove_ob (hitter); |
2011 | |
2021 | free_object (hitter); |
|
|
2022 | } |
|
|
2023 | return maxdam; |
2012 | return maxdam; |
2024 | } |
2013 | } |
2025 | |
2014 | |
2026 | |
2015 | |
2027 | void |
2016 | void |
… | |
… | |
2048 | if (QUERY_FLAG (hitter, FLAG_ALIVE)) |
2037 | if (QUERY_FLAG (hitter, FLAG_ALIVE)) |
2049 | tmp->stats.dam += hitter->level / 2; |
2038 | tmp->stats.dam += hitter->level / 2; |
2050 | else |
2039 | else |
2051 | tmp->stats.dam = dam; |
2040 | tmp->stats.dam = dam; |
2052 | |
2041 | |
2053 | copy_owner (tmp, hitter); /* so we get credit for poisoning kills */ |
2042 | tmp->set_owner (hitter); /* so we get credit for poisoning kills */ |
2054 | if (hitter->skill && hitter->skill != tmp->skill) |
2043 | if (hitter->skill && hitter->skill != tmp->skill) |
2055 | { |
2044 | { |
2056 | tmp->skill = hitter->skill; |
2045 | tmp->skill = hitter->skill; |
2057 | } |
2046 | } |
2058 | |
2047 | |
… | |
… | |
2069 | fix_player (op); |
2058 | fix_player (op); |
2070 | new_draw_info (NDI_UNIQUE, 0, op, "You suddenly feel very ill."); |
2059 | new_draw_info (NDI_UNIQUE, 0, op, "You suddenly feel very ill."); |
2071 | } |
2060 | } |
2072 | if (hitter->type == PLAYER) |
2061 | if (hitter->type == PLAYER) |
2073 | new_draw_info_format (NDI_UNIQUE, 0, hitter, "You poison %s.", &op->name); |
2062 | new_draw_info_format (NDI_UNIQUE, 0, hitter, "You poison %s.", &op->name); |
2074 | else if (get_owner (hitter) != NULL && hitter->owner->type == PLAYER) |
2063 | else if (hitter->owner != NULL && hitter->owner->type == PLAYER) |
2075 | new_draw_info_format (NDI_UNIQUE, 0, hitter->owner, "Your %s poisons %s.", &hitter->name, &op->name); |
2064 | new_draw_info_format (NDI_UNIQUE, 0, hitter->owner, "Your %s poisons %s.", &hitter->name, &op->name); |
2076 | } |
2065 | } |
2077 | tmp->speed_left = 0; |
2066 | tmp->speed_left = 0; |
2078 | } |
2067 | } |
2079 | else |
2068 | else |
… | |
… | |
2155 | tmp = insert_ob_in_ob (tmp, op); |
2144 | tmp = insert_ob_in_ob (tmp, op); |
2156 | change_abil (op, tmp); /* Mostly to display any messages */ |
2145 | change_abil (op, tmp); /* Mostly to display any messages */ |
2157 | fix_player (op); /* This takes care of some other stuff */ |
2146 | fix_player (op); /* This takes care of some other stuff */ |
2158 | |
2147 | |
2159 | if (hitter->owner) |
2148 | if (hitter->owner) |
2160 | owner = get_owner (hitter); |
2149 | owner = hitter->owner; |
2161 | else |
2150 | else |
2162 | owner = hitter; |
2151 | owner = hitter; |
2163 | |
2152 | |
2164 | new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op)); |
2153 | new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op)); |
2165 | } |
2154 | } |
… | |
… | |
2311 | } |
2300 | } |
2312 | |
2301 | |
2313 | /* aimed missiles use the owning object's sight */ |
2302 | /* aimed missiles use the owning object's sight */ |
2314 | if (is_aimed_missile (hitter)) |
2303 | if (is_aimed_missile (hitter)) |
2315 | { |
2304 | { |
2316 | if ((attacker = get_owner (hitter)) == NULL) |
2305 | if ((attacker = hitter->owner) == NULL) |
2317 | attacker = hitter; |
2306 | attacker = hitter; |
2318 | /* A player who saves but hasn't quit still could have objects |
2307 | /* A player who saves but hasn't quit still could have objects |
2319 | * owned by him - need to handle that case to avoid crashes. |
2308 | * owned by him - need to handle that case to avoid crashes. |
2320 | */ |
2309 | */ |
2321 | if (QUERY_FLAG (attacker, FLAG_REMOVED)) |
2310 | if (QUERY_FLAG (attacker, FLAG_REMOVED)) |