1 | |
|
|
2 | /* |
|
|
3 | * static char *rcsid_time_c = |
|
|
4 | * "$Id: time.C,v 1.10 2006/09/11 20:26:41 root Exp $"; |
|
|
5 | */ |
|
|
6 | |
|
|
7 | /* |
1 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
2 | CrossFire, A Multiplayer game for X-windows |
9 | |
3 | |
10 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
4 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
11 | Copyright (C) 1992 Frank Tore Johansen |
5 | Copyright (C) 1992 Frank Tore Johansen |
… | |
… | |
22 | |
16 | |
23 | 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 |
24 | along with this program; if not, write to the Free Software |
18 | along with this program; if not, write to the Free Software |
25 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | |
20 | |
27 | 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> |
28 | */ |
22 | */ |
29 | |
23 | |
30 | /* |
24 | /* |
31 | * Routines that is executed from objects based on their speed have been |
25 | * Routines that is executed from objects based on their speed have been |
32 | * collected in this file. |
26 | * collected in this file. |
… | |
… | |
64 | tmp->y = op->y; |
58 | tmp->y = op->y; |
65 | tmp->map = op->map; |
59 | tmp->map = op->map; |
66 | tmp->level = op->level; |
60 | tmp->level = op->level; |
67 | insert_ob_in_map (tmp, op->map, op, 0); |
61 | insert_ob_in_map (tmp, op->map, op, 0); |
68 | } |
62 | } |
69 | remove_ob (op); |
63 | |
70 | free_object (op); |
64 | op->destroy (); |
71 | } |
65 | } |
72 | |
66 | |
73 | void |
67 | void |
74 | remove_door2 (object *op) |
68 | remove_door2 (object *op) |
75 | { |
69 | { |
… | |
… | |
93 | tmp->y = op->y; |
87 | tmp->y = op->y; |
94 | tmp->map = op->map; |
88 | tmp->map = op->map; |
95 | tmp->level = op->level; |
89 | tmp->level = op->level; |
96 | insert_ob_in_map (tmp, op->map, op, 0); |
90 | insert_ob_in_map (tmp, op->map, op, 0); |
97 | } |
91 | } |
98 | remove_ob (op); |
92 | |
99 | free_object (op); |
93 | op->destroy (); |
100 | } |
94 | } |
101 | |
95 | |
102 | /* Will generate a monster according to content |
96 | /* Will generate a monster according to content |
103 | * of generator. |
97 | * of generator. |
104 | */ |
98 | */ |
… | |
… | |
139 | if (rndm (0, 9)) |
133 | if (rndm (0, 9)) |
140 | generate_artifact (head, gen->map->difficulty); |
134 | generate_artifact (head, gen->map->difficulty); |
141 | insert_ob_in_map_at (head, gen->map, gen, 0, gen->x + freearr_x[i], gen->y + freearr_y[i]); |
135 | insert_ob_in_map_at (head, gen->map, gen, 0, gen->x + freearr_x[i], gen->y + freearr_y[i]); |
142 | if (QUERY_FLAG (head, FLAG_FREED)) |
136 | if (QUERY_FLAG (head, FLAG_FREED)) |
143 | return; |
137 | return; |
144 | if (HAS_RANDOM_ITEMS (head)) |
138 | if (head->has_random_items ()) |
145 | create_treasure (head->randomitems, head, GT_APPLY, gen->map->difficulty, 0); |
139 | create_treasure (head->randomitems, head, GT_APPLY, gen->map->difficulty, 0); |
146 | } |
140 | } |
147 | |
141 | |
148 | void |
142 | void |
149 | generate_monster_arch (object *gen) |
143 | generate_monster_arch (object *gen) |
… | |
… | |
181 | if (rndm (0, 9)) |
175 | if (rndm (0, 9)) |
182 | generate_artifact (op, gen->map->difficulty); |
176 | generate_artifact (op, gen->map->difficulty); |
183 | insert_ob_in_map (op, gen->map, gen, 0); |
177 | insert_ob_in_map (op, gen->map, gen, 0); |
184 | if (QUERY_FLAG (op, FLAG_FREED)) |
178 | if (QUERY_FLAG (op, FLAG_FREED)) |
185 | return; |
179 | return; |
186 | if (HAS_RANDOM_ITEMS (op)) |
180 | if (op->has_random_items ()) |
187 | create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty, 0); |
181 | create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty, 0); |
188 | if (head == NULL) |
182 | if (head == NULL) |
189 | head = op; |
183 | head = op; |
190 | prev = op; |
184 | prev = op; |
191 | at = at->more; |
185 | at = at->more; |
… | |
… | |
226 | CLEAR_FLAG (op, FLAG_APPLIED); |
220 | CLEAR_FLAG (op, FLAG_APPLIED); |
227 | change_abil (op->env, op); |
221 | change_abil (op->env, op); |
228 | fix_player (op->env); |
222 | fix_player (op->env); |
229 | } |
223 | } |
230 | } |
224 | } |
231 | remove_ob (op); |
225 | |
232 | free_object (op); |
226 | op->destroy (); |
233 | } |
227 | } |
234 | |
228 | |
235 | void |
229 | void |
236 | remove_blindness (object *op) |
230 | remove_blindness (object *op) |
237 | { |
231 | { |
238 | if (--op->stats.food > 0) |
232 | if (--op->stats.food > 0) |
239 | return; |
233 | return; |
|
|
234 | |
240 | CLEAR_FLAG (op, FLAG_APPLIED); |
235 | CLEAR_FLAG (op, FLAG_APPLIED); |
|
|
236 | |
241 | if (op->env != NULL) |
237 | if (op->env != NULL) |
242 | { |
238 | { |
243 | change_abil (op->env, op); |
239 | change_abil (op->env, op); |
244 | fix_player (op->env); |
240 | fix_player (op->env); |
245 | } |
241 | } |
246 | remove_ob (op); |
242 | |
247 | free_object (op); |
243 | op->destroy (); |
248 | } |
244 | } |
249 | |
245 | |
250 | void |
246 | void |
251 | poison_more (object *op) |
247 | poison_more (object *op) |
252 | { |
248 | { |
253 | if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0) |
249 | if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0) |
254 | { |
250 | { |
255 | remove_ob (op); |
251 | op->destroy (); |
256 | free_object (op); |
|
|
257 | return; |
252 | return; |
258 | } |
253 | } |
|
|
254 | |
259 | if (op->stats.food == 1) |
255 | if (op->stats.food == 1) |
260 | { |
256 | { |
261 | /* need to remove the object before fix_player is called, else fix_player |
257 | /* need to remove the object before fix_player is called, else fix_player |
262 | * will not do anything. |
258 | * will not do anything. |
263 | */ |
259 | */ |
… | |
… | |
265 | { |
261 | { |
266 | CLEAR_FLAG (op, FLAG_APPLIED); |
262 | CLEAR_FLAG (op, FLAG_APPLIED); |
267 | fix_player (op->env); |
263 | fix_player (op->env); |
268 | new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now."); |
264 | new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now."); |
269 | } |
265 | } |
270 | remove_ob (op); |
266 | |
271 | free_object (op); |
267 | op->destroy (); |
272 | return; |
268 | return; |
273 | } |
269 | } |
|
|
270 | |
274 | if (op->env->type == PLAYER) |
271 | if (op->env->type == PLAYER) |
275 | { |
272 | { |
276 | op->env->stats.food--; |
273 | op->env->stats.food--; |
277 | new_draw_info (NDI_UNIQUE, 0, op->env, "You feel very sick..."); |
274 | new_draw_info (NDI_UNIQUE, 0, op->env, "You feel very sick..."); |
278 | } |
275 | } |
… | |
… | |
286 | object *tmp; |
283 | object *tmp; |
287 | |
284 | |
288 | if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op)) |
285 | if (op->stats.wc < 0 || (int) op->stats.wc >= NUM_ANIMATIONS (op)) |
289 | { |
286 | { |
290 | LOG (llevError, "Gate error: animation was %d, max=%d\n", op->stats.wc, NUM_ANIMATIONS (op)); |
287 | LOG (llevError, "Gate error: animation was %d, max=%d\n", op->stats.wc, NUM_ANIMATIONS (op)); |
291 | dump_object (op); |
|
|
292 | LOG (llevError, "%s\n", errmsg); |
|
|
293 | op->stats.wc = 0; |
288 | op->stats.wc = 0; |
294 | } |
289 | } |
295 | |
290 | |
296 | /* We're going down */ |
291 | /* We're going down */ |
297 | if (op->value) |
292 | if (op->value) |
… | |
… | |
390 | int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); |
385 | int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); |
391 | |
386 | |
392 | /* If there is a free spot, move the object someplace */ |
387 | /* If there is a free spot, move the object someplace */ |
393 | if (i != -1) |
388 | if (i != -1) |
394 | { |
389 | { |
395 | remove_ob (tmp); |
390 | tmp->remove (); |
396 | tmp->x += freearr_x[i], tmp->y += freearr_y[i]; |
391 | tmp->x += freearr_x[i], tmp->y += freearr_y[i]; |
397 | insert_ob_in_map (tmp, op->map, op, 0); |
392 | insert_ob_in_map (tmp, op->map, op, 0); |
398 | } |
393 | } |
399 | } |
394 | } |
400 | } |
395 | } |
… | |
… | |
464 | int last = op->value; |
459 | int last = op->value; |
465 | int detected; |
460 | int detected; |
466 | |
461 | |
467 | detected = 0; |
462 | detected = 0; |
468 | |
463 | |
469 | for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL && !detected; tmp = tmp->above) |
464 | for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL && !detected; tmp = tmp->above) |
470 | { |
465 | { |
471 | object *tmp2; |
466 | object *tmp2; |
472 | |
467 | |
473 | if (op->stats.hp) |
468 | if (op->stats.hp) |
474 | { |
469 | { |
… | |
… | |
599 | { |
594 | { |
600 | object *payload = op->inv; |
595 | object *payload = op->inv; |
601 | |
596 | |
602 | if (payload == NULL) |
597 | if (payload == NULL) |
603 | return NULL; |
598 | return NULL; |
604 | remove_ob (payload); |
599 | payload->remove (); |
605 | remove_ob (op); |
600 | op->destroy (); |
606 | free_object (op); |
|
|
607 | return payload; |
601 | return payload; |
608 | } |
602 | } |
609 | |
603 | |
610 | case ARROW: |
604 | case ARROW: |
611 | if (op->speed >= MIN_ACTIVE_SPEED) |
605 | if (op->speed >= MIN_ACTIVE_SPEED) |
… | |
… | |
621 | * Inserts item into the old map, or merges it if it already is on the map. |
615 | * Inserts item into the old map, or merges it if it already is on the map. |
622 | * |
616 | * |
623 | * 'map' must be the value of op->map before stop_item() was called. |
617 | * 'map' must be the value of op->map before stop_item() was called. |
624 | */ |
618 | */ |
625 | void |
619 | void |
626 | fix_stopped_item (object *op, mapstruct *map, object *originator) |
620 | fix_stopped_item (object *op, maptile *map, object *originator) |
627 | { |
621 | { |
628 | if (map == NULL) |
622 | if (map == NULL) |
629 | return; |
623 | return; |
630 | if (QUERY_FLAG (op, FLAG_REMOVED)) |
624 | if (QUERY_FLAG (op, FLAG_REMOVED)) |
631 | insert_ob_in_map (op, map, originator, 0); |
625 | insert_ob_in_map (op, map, originator, 0); |
… | |
… | |
638 | fix_stopped_arrow (object *op) |
632 | fix_stopped_arrow (object *op) |
639 | { |
633 | { |
640 | if (rndm (0, 99) < op->stats.food) |
634 | if (rndm (0, 99) < op->stats.food) |
641 | { |
635 | { |
642 | /* Small chance of breaking */ |
636 | /* Small chance of breaking */ |
643 | remove_ob (op); |
637 | op->destroy (); |
644 | free_object (op); |
|
|
645 | return NULL; |
638 | return NULL; |
646 | } |
639 | } |
647 | |
640 | |
648 | op->direction = 0; |
641 | op->direction = 0; |
649 | op->move_on = 0; |
642 | op->move_on = 0; |
… | |
… | |
663 | op->spellarg = NULL; |
656 | op->spellarg = NULL; |
664 | } |
657 | } |
665 | else |
658 | else |
666 | op->slaying = NULL; |
659 | op->slaying = NULL; |
667 | |
660 | |
668 | /* Reset these to zero, so that CAN_MERGE will work properly */ |
661 | /* Reset these to zero, so that object::can_merge will work properly */ |
669 | op->spellarg = NULL; |
662 | op->spellarg = NULL; |
670 | op->stats.sp = 0; |
663 | op->stats.sp = 0; |
671 | op->stats.hp = 0; |
664 | op->stats.hp = 0; |
672 | op->stats.grace = 0; |
665 | op->stats.grace = 0; |
673 | op->level = 0; |
666 | op->level = 0; |
… | |
… | |
693 | |
686 | |
694 | if (op->inv) |
687 | if (op->inv) |
695 | { |
688 | { |
696 | object *payload = op->inv; |
689 | object *payload = op->inv; |
697 | |
690 | |
698 | remove_ob (payload); |
691 | payload->remove (); |
699 | clear_owner (payload); |
692 | payload->owner = 0; |
700 | insert_ob_in_map (payload, op->map, payload, 0); |
693 | insert_ob_in_map (payload, op->map, payload, 0); |
701 | remove_ob (op); |
694 | op->destroy (); |
702 | free_object (op); |
|
|
703 | } |
695 | } |
704 | else |
696 | else |
705 | { |
697 | { |
706 | op = fix_stopped_arrow (op); |
698 | op = fix_stopped_arrow (op); |
707 | if (op) |
699 | if (op) |
… | |
… | |
716 | move_arrow (object *op) |
708 | move_arrow (object *op) |
717 | { |
709 | { |
718 | object *tmp; |
710 | object *tmp; |
719 | sint16 new_x, new_y; |
711 | sint16 new_x, new_y; |
720 | int was_reflected, mflags; |
712 | int was_reflected, mflags; |
721 | mapstruct *m; |
713 | maptile *m; |
722 | |
714 | |
723 | if (op->map == NULL) |
715 | if (op->map == NULL) |
724 | { |
716 | { |
725 | LOG (llevError, "BUG: Arrow had no map.\n"); |
717 | LOG (llevError, "BUG: Arrow had no map.\n"); |
726 | remove_ob (op); |
718 | op->destroy (); |
727 | free_object (op); |
|
|
728 | return; |
719 | return; |
729 | } |
720 | } |
730 | |
721 | |
731 | /* we need to stop thrown objects at some point. Like here. */ |
722 | /* we need to stop thrown objects at some point. Like here. */ |
732 | if (op->type == THROWN_OBJ) |
723 | if (op->type == THROWN_OBJ) |
… | |
… | |
739 | * bomb code, but there are potential other cases where that could happen, |
730 | * bomb code, but there are potential other cases where that could happen, |
740 | * and it is easy enough to clean it up here. |
731 | * and it is easy enough to clean it up here. |
741 | */ |
732 | */ |
742 | if (op->inv == NULL) |
733 | if (op->inv == NULL) |
743 | { |
734 | { |
744 | remove_ob (op); |
735 | op->destroy (); |
745 | free_object (op); |
|
|
746 | return; |
736 | return; |
747 | } |
737 | } |
|
|
738 | |
748 | if (op->last_sp-- < 0) |
739 | if (op->last_sp-- < 0) |
749 | { |
740 | { |
750 | stop_arrow (op); |
741 | stop_arrow (op); |
751 | return; |
742 | return; |
752 | } |
743 | } |
… | |
… | |
775 | } |
766 | } |
776 | |
767 | |
777 | /* only need to look for living creatures if this flag is set */ |
768 | /* only need to look for living creatures if this flag is set */ |
778 | if (mflags & P_IS_ALIVE) |
769 | if (mflags & P_IS_ALIVE) |
779 | { |
770 | { |
780 | for (tmp = get_map_ob (m, new_x, new_y); tmp != NULL; tmp = tmp->above) |
771 | for (tmp = GET_MAP_OB (m, new_x, new_y); tmp != NULL; tmp = tmp->above) |
781 | if (QUERY_FLAG (tmp, FLAG_ALIVE)) |
772 | if (QUERY_FLAG (tmp, FLAG_ALIVE)) |
782 | break; |
773 | break; |
783 | |
|
|
784 | |
774 | |
785 | /* Not really fair, but don't let monsters hit themselves with |
775 | /* Not really fair, but don't let monsters hit themselves with |
786 | * their own arrow - this can be because they fire it then |
776 | * their own arrow - this can be because they fire it then |
787 | * move into it. |
777 | * move into it. |
788 | */ |
778 | */ |
789 | |
|
|
790 | if (tmp != NULL && tmp != op->owner) |
779 | if (tmp && tmp != op->owner) |
791 | { |
780 | { |
792 | /* Found living object, but it is reflecting the missile. Update |
781 | /* Found living object, but it is reflecting the missile. Update |
793 | * as below. (Note that for living creatures there is a small |
782 | * as below. (Note that for living creatures there is a small |
794 | * chance that reflect_missile fails.) |
783 | * chance that reflect_missile fails.) |
795 | */ |
784 | */ |
796 | |
|
|
797 | if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && (rndm (0, 99)) < (90 - op->level / 10)) |
785 | if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && (rndm (0, 99)) < (90 - op->level / 10)) |
798 | { |
786 | { |
799 | |
|
|
800 | int number = op->face->number; |
787 | int number = op->face->number; |
801 | |
788 | |
802 | op->direction = absdir (op->direction + 4); |
789 | op->direction = absdir (op->direction + 4); |
803 | op->state = 0; |
790 | op->state = 0; |
|
|
791 | |
804 | if (GET_ANIM_ID (op)) |
792 | if (GET_ANIM_ID (op)) |
805 | { |
793 | { |
806 | number += 4; |
794 | number += 4; |
|
|
795 | |
807 | if (number > GET_ANIMATION (op, 8)) |
796 | if (number > GET_ANIMATION (op, 8)) |
808 | number -= 8; |
797 | number -= 8; |
|
|
798 | |
809 | op->face = &new_faces[number]; |
799 | op->face = &new_faces[number]; |
810 | } |
800 | } |
|
|
801 | |
811 | was_reflected = 1; /* skip normal movement calculations */ |
802 | was_reflected = 1; /* skip normal movement calculations */ |
812 | } |
803 | } |
813 | else |
804 | else |
814 | { |
805 | { |
815 | /* Attack the object. */ |
806 | /* Attack the object. */ |
816 | op = hit_with_arrow (op, tmp); |
807 | op = hit_with_arrow (op, tmp); |
|
|
808 | |
817 | if (op == NULL) |
809 | if (!op) |
818 | return; |
810 | return; |
819 | } |
811 | } |
820 | } /* if this is not hitting its owner */ |
812 | } /* if this is not hitting its owner */ |
821 | } /* if there is something alive on this space */ |
813 | } /* if there is something alive on this space */ |
822 | |
|
|
823 | |
814 | |
824 | if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))) |
815 | if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))) |
825 | { |
816 | { |
826 | int retry = 0; |
817 | int retry = 0; |
827 | |
818 | |
… | |
… | |
849 | * that did the same thing. |
840 | * that did the same thing. |
850 | */ |
841 | */ |
851 | while (retry < 2) |
842 | while (retry < 2) |
852 | { |
843 | { |
853 | int left, right, mflags; |
844 | int left, right, mflags; |
854 | mapstruct *m1; |
845 | maptile *m1; |
855 | sint16 x1, y1; |
846 | sint16 x1, y1; |
856 | |
847 | |
857 | retry++; |
848 | retry++; |
858 | |
849 | |
859 | /* Need to check for P_OUT_OF_MAP: if the arrow is tavelling |
850 | /* Need to check for P_OUT_OF_MAP: if the arrow is tavelling |
… | |
… | |
899 | SET_ANIMATION (op, op->direction); |
890 | SET_ANIMATION (op, op->direction); |
900 | } /* object is reflected */ |
891 | } /* object is reflected */ |
901 | } /* object ran into a wall */ |
892 | } /* object ran into a wall */ |
902 | |
893 | |
903 | /* Move the arrow. */ |
894 | /* Move the arrow. */ |
904 | remove_ob (op); |
895 | op->remove (); |
905 | op->x = new_x; |
896 | op->x = new_x; |
906 | op->y = new_y; |
897 | op->y = new_y; |
907 | |
898 | |
908 | /* decrease the speed as it flies. 0.05 means a standard bow will shoot |
899 | /* decrease the speed as it flies. 0.05 means a standard bow will shoot |
909 | * about 17 squares. Tune as needed. |
900 | * about 17 squares. Tune as needed. |
… | |
… | |
917 | * Modified this routine to allow held objects. b.t. */ |
908 | * Modified this routine to allow held objects. b.t. */ |
918 | |
909 | |
919 | void |
910 | void |
920 | change_object (object *op) |
911 | change_object (object *op) |
921 | { /* Doesn`t handle linked objs yet */ |
912 | { /* Doesn`t handle linked objs yet */ |
922 | object *tmp, *env, *pl; |
|
|
923 | int i, j; |
913 | int i, j; |
924 | |
914 | |
925 | if (op->other_arch == NULL) |
915 | if (op->other_arch == NULL) |
926 | { |
916 | { |
927 | LOG (llevError, "Change object (%s) without other_arch error.\n", &op->name); |
917 | LOG (llevError, "Change object (%s) without other_arch error.\n", &op->name); |
… | |
… | |
934 | if (op->stats.food-- > 0) |
924 | if (op->stats.food-- > 0) |
935 | return; |
925 | return; |
936 | else |
926 | else |
937 | op->stats.food = 1; /* so 1 other_arch is made */ |
927 | op->stats.food = 1; /* so 1 other_arch is made */ |
938 | } |
928 | } |
|
|
929 | |
|
|
930 | object *pl = op->in_player (); |
939 | env = op->env; |
931 | object *env = op->env; |
940 | remove_ob (op); |
932 | |
|
|
933 | op->remove (); |
941 | for (i = 0; i < NROFNEWOBJS (op); i++) |
934 | for (i = 0; i < NROFNEWOBJS (op); i++) |
942 | { |
935 | { |
943 | tmp = arch_to_object (op->other_arch); |
936 | object *tmp = arch_to_object (op->other_arch); |
|
|
937 | |
944 | if (op->type == LAMP) |
938 | if (op->type == LAMP) |
945 | tmp->stats.food = op->stats.food - 1; |
939 | tmp->stats.food = op->stats.food - 1; |
|
|
940 | |
946 | tmp->stats.hp = op->stats.hp; /* The only variable it keeps. */ |
941 | tmp->stats.hp = op->stats.hp; /* The only variable it keeps. */ |
947 | if (env) |
942 | if (env) |
948 | { |
943 | { |
949 | tmp->x = env->x, tmp->y = env->y; |
944 | tmp->x = env->x, tmp->y = env->y; |
950 | tmp = insert_ob_in_ob (tmp, env); |
945 | tmp = insert_ob_in_ob (tmp, env); |
|
|
946 | |
951 | /* If this object is the players inventory, we need to tell the |
947 | /* If this object is the players inventory, we need to tell the |
952 | * client of the change. Insert_ob_in_map takes care of the |
948 | * client of the change. Insert_ob_in_map takes care of the |
953 | * updating the client, so we don't need to do that below. |
949 | * updating the client, so we don't need to do that below. |
954 | */ |
950 | */ |
955 | if ((pl = is_player_inv (env)) != NULL) |
951 | if (pl) |
956 | { |
952 | { |
957 | esrv_del_item (pl->contr, op->count); |
953 | esrv_del_item (pl->contr, op->count); |
958 | esrv_send_item (pl, tmp); |
954 | esrv_send_item (pl, tmp); |
959 | } |
955 | } |
960 | } |
956 | } |
961 | else |
957 | else |
962 | { |
958 | { |
963 | j = find_first_free_spot (tmp, op->map, op->x, op->y); |
959 | j = find_first_free_spot (tmp, op->map, op->x, op->y); |
964 | if (j == -1) /* No free spot */ |
960 | if (j == -1) /* No free spot */ |
965 | free_object (tmp); |
961 | tmp->destroy (); |
966 | else |
962 | else |
967 | { |
963 | { |
968 | tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j]; |
964 | tmp->x = op->x + freearr_x[j], tmp->y = op->y + freearr_y[j]; |
969 | insert_ob_in_map (tmp, op->map, op, 0); |
965 | insert_ob_in_map (tmp, op->map, op, 0); |
970 | } |
966 | } |
971 | } |
967 | } |
972 | } |
968 | } |
973 | free_object (op); |
969 | |
|
|
970 | op->destroy (); |
974 | } |
971 | } |
975 | |
972 | |
976 | void |
973 | void |
977 | move_teleporter (object *op) |
974 | move_teleporter (object *op) |
978 | { |
975 | { |
… | |
… | |
1015 | else if (EXIT_X (head) || EXIT_Y (head)) |
1012 | else if (EXIT_X (head) || EXIT_Y (head)) |
1016 | { |
1013 | { |
1017 | if (out_of_map (head->map, EXIT_X (head), EXIT_Y (head))) |
1014 | if (out_of_map (head->map, EXIT_X (head), EXIT_Y (head))) |
1018 | { |
1015 | { |
1019 | LOG (llevError, "Removed illegal teleporter.\n"); |
1016 | LOG (llevError, "Removed illegal teleporter.\n"); |
1020 | remove_ob (head); |
1017 | head->destroy (); |
1021 | free_object (head); |
|
|
1022 | return; |
1018 | return; |
1023 | } |
1019 | } |
|
|
1020 | |
1024 | if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp))) |
1021 | if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp))) |
1025 | return; |
1022 | return; |
|
|
1023 | |
1026 | transfer_ob (tmp, EXIT_X (head), EXIT_Y (head), 0, head); |
1024 | transfer_ob (tmp, EXIT_X (head), EXIT_Y (head), 0, head); |
1027 | } |
1025 | } |
1028 | else |
1026 | else |
1029 | { |
1027 | { |
1030 | /* Random teleporter */ |
1028 | /* Random teleporter */ |
… | |
… | |
1122 | move_player_mover (object *op) |
1120 | move_player_mover (object *op) |
1123 | { |
1121 | { |
1124 | object *victim, *nextmover; |
1122 | object *victim, *nextmover; |
1125 | int dir = op->stats.sp; |
1123 | int dir = op->stats.sp; |
1126 | sint16 nx, ny; |
1124 | sint16 nx, ny; |
1127 | mapstruct *m; |
1125 | maptile *m; |
1128 | |
1126 | |
1129 | /* Determine direction now for random movers so we do the right thing */ |
1127 | /* Determine direction now for random movers so we do the right thing */ |
1130 | if (!dir) |
1128 | if (!dir) |
1131 | dir = rndm (1, 8); |
1129 | dir = rndm (1, 8); |
1132 | |
1130 | |
1133 | for (victim = get_map_ob (op->map, op->x, op->y); victim != NULL; victim = victim->above) |
1131 | for (victim = GET_MAP_OB (op->map, op->x, op->y); victim != NULL; victim = victim->above) |
1134 | { |
1132 | { |
1135 | if (QUERY_FLAG (victim, FLAG_ALIVE) && !QUERY_FLAG (victim, FLAG_WIZPASS) && |
1133 | if (QUERY_FLAG (victim, FLAG_ALIVE) && !QUERY_FLAG (victim, FLAG_WIZPASS) && |
1136 | (victim->move_type & op->move_type || !victim->move_type)) |
1134 | (victim->move_type & op->move_type || !victim->move_type)) |
1137 | { |
1135 | { |
1138 | |
1136 | |
1139 | if (victim->head) |
1137 | if (victim->head) |
1140 | victim = victim->head; |
1138 | victim = victim->head; |
1141 | |
1139 | |
1142 | if (QUERY_FLAG (op, FLAG_LIFESAVE) && op->stats.hp-- < 0) |
1140 | if (QUERY_FLAG (op, FLAG_LIFESAVE) && op->stats.hp-- < 0) |
1143 | { |
1141 | { |
1144 | remove_ob (op); |
1142 | op->remove (); |
1145 | free_object (op); |
|
|
1146 | return; |
1143 | return; |
1147 | } |
1144 | } |
|
|
1145 | |
1148 | nx = op->x + freearr_x[dir]; |
1146 | nx = op->x + freearr_x[dir]; |
1149 | ny = op->y + freearr_y[dir]; |
1147 | ny = op->y + freearr_y[dir]; |
1150 | m = op->map; |
1148 | m = op->map; |
1151 | if (get_map_flags (m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP) |
1149 | if (get_map_flags (m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP) |
1152 | { |
1150 | { |
… | |
… | |
1155 | } |
1153 | } |
1156 | |
1154 | |
1157 | if (should_director_abort (op, victim)) |
1155 | if (should_director_abort (op, victim)) |
1158 | return; |
1156 | return; |
1159 | |
1157 | |
1160 | for (nextmover = get_map_ob (m, nx, ny); nextmover != NULL; nextmover = nextmover->above) |
1158 | for (nextmover = GET_MAP_OB (m, nx, ny); nextmover != NULL; nextmover = nextmover->above) |
1161 | { |
1159 | { |
1162 | if (nextmover->type == PLAYERMOVER) |
1160 | if (nextmover->type == PLAYERMOVER) |
1163 | nextmover->speed_left = -.99; |
1161 | nextmover->speed_left = -.99; |
1164 | if (QUERY_FLAG (nextmover, FLAG_ALIVE)) |
1162 | if (QUERY_FLAG (nextmover, FLAG_ALIVE)) |
1165 | { |
1163 | { |
… | |
… | |
1230 | for (tmp = op->above; tmp != NULL; tmp = tmp->above) |
1228 | for (tmp = op->above; tmp != NULL; tmp = tmp->above) |
1231 | { |
1229 | { |
1232 | if (strcmp (op->other_arch->name, tmp->arch->name) == 0) |
1230 | if (strcmp (op->other_arch->name, tmp->arch->name) == 0) |
1233 | { |
1231 | { |
1234 | if (op->level <= 0) |
1232 | if (op->level <= 0) |
1235 | { |
1233 | tmp->destroy (); |
1236 | remove_ob (tmp); |
|
|
1237 | free_object (tmp); |
|
|
1238 | } |
|
|
1239 | else |
1234 | else |
1240 | { |
1235 | { |
1241 | uint64 new_nrof = (uint64) tmp->nrof * op->level; |
1236 | uint64 new_nrof = (uint64) tmp->nrof * op->level; |
1242 | |
1237 | |
1243 | if (new_nrof >= 1UL << 31) |
1238 | if (new_nrof >= 1UL << 31) |
1244 | new_nrof = 1UL << 31; |
1239 | new_nrof = 1UL << 31; |
|
|
1240 | |
1245 | tmp->nrof = new_nrof; |
1241 | tmp->nrof = new_nrof; |
1246 | } |
1242 | } |
|
|
1243 | |
1247 | break; |
1244 | break; |
1248 | } |
1245 | } |
1249 | } |
1246 | } |
1250 | } |
1247 | } |
1251 | |
1248 | |
… | |
… | |
1307 | } |
1304 | } |
1308 | |
1305 | |
1309 | /* Make sure this multipart object fits */ |
1306 | /* Make sure this multipart object fits */ |
1310 | if (new_ob->arch->more && ob_blocked (new_ob, creator->map, creator->x, creator->y)) |
1307 | if (new_ob->arch->more && ob_blocked (new_ob, creator->map, creator->x, creator->y)) |
1311 | { |
1308 | { |
1312 | free_object (new_ob); |
1309 | new_ob->destroy (); |
1313 | return; |
1310 | return; |
1314 | } |
1311 | } |
1315 | |
1312 | |
1316 | insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y); |
1313 | insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y); |
1317 | if (QUERY_FLAG (new_ob, FLAG_FREED)) |
1314 | if (QUERY_FLAG (new_ob, FLAG_FREED)) |
… | |
… | |
1335 | void |
1332 | void |
1336 | move_marker (object *op) |
1333 | move_marker (object *op) |
1337 | { |
1334 | { |
1338 | object *tmp, *tmp2; |
1335 | object *tmp, *tmp2; |
1339 | |
1336 | |
1340 | for (tmp = get_map_ob (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) |
1337 | for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) |
1341 | { |
1338 | { |
1342 | if (tmp->type == PLAYER) |
1339 | if (tmp->type == PLAYER) |
1343 | { /* we've got someone to MARK */ |
1340 | { /* we've got someone to MARK */ |
1344 | |
1341 | |
1345 | /* remove an old force with a slaying field == op->name */ |
1342 | /* remove an old force with a slaying field == op->name */ |
… | |
… | |
1348 | if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->name)) |
1345 | if (tmp2->type == FORCE && tmp2->slaying && !strcmp (tmp2->slaying, op->name)) |
1349 | break; |
1346 | break; |
1350 | } |
1347 | } |
1351 | |
1348 | |
1352 | if (tmp2) |
1349 | if (tmp2) |
1353 | { |
1350 | tmp2->destroy (); |
1354 | remove_ob (tmp2); |
|
|
1355 | free_object (tmp2); |
|
|
1356 | } |
|
|
1357 | |
1351 | |
1358 | /* cycle through his inventory to look for the MARK we want to |
1352 | /* cycle through his inventory to look for the MARK we want to |
1359 | * place |
1353 | * place |
1360 | */ |
1354 | */ |
1361 | for (tmp2 = tmp->inv; tmp2 != NULL; tmp2 = tmp2->below) |
1355 | for (tmp2 = tmp->inv; tmp2 != NULL; tmp2 = tmp2->below) |
… | |
… | |
1390 | { |
1384 | { |
1391 | op->stats.hp--; |
1385 | op->stats.hp--; |
1392 | if (op->stats.hp == 0) |
1386 | if (op->stats.hp == 0) |
1393 | { |
1387 | { |
1394 | /* marker expires--granted mark number limit */ |
1388 | /* marker expires--granted mark number limit */ |
1395 | remove_ob (op); |
1389 | op->destroy (); |
1396 | free_object (op); |
|
|
1397 | return; |
1390 | return; |
1398 | } |
1391 | } |
1399 | } |
1392 | } |
1400 | } /* if tmp2 == NULL */ |
1393 | } /* if tmp2 == NULL */ |
1401 | } /* if tmp->type == PLAYER */ |
1394 | } /* if tmp->type == PLAYER */ |
… | |
… | |
1440 | if (QUERY_FLAG (op, FLAG_APPLIED)) |
1433 | if (QUERY_FLAG (op, FLAG_APPLIED)) |
1441 | remove_force (op); |
1434 | remove_force (op); |
1442 | else |
1435 | else |
1443 | { |
1436 | { |
1444 | /* IF necessary, delete the item from the players inventory */ |
1437 | /* IF necessary, delete the item from the players inventory */ |
1445 | object *pl = is_player_inv (op); |
1438 | object *pl = op->in_player (); |
1446 | |
1439 | |
1447 | if (pl) |
1440 | if (pl) |
1448 | esrv_del_item (pl->contr, op->count); |
1441 | esrv_del_item (pl->contr, op->count); |
1449 | |
1442 | |
1450 | remove_ob (op); |
1443 | op->remove (); |
1451 | |
1444 | |
1452 | if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) |
1445 | if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) |
1453 | make_sure_not_seen (op); |
1446 | make_sure_not_seen (op); |
1454 | |
1447 | |
1455 | free_object (op); |
1448 | op->destroy (); |
1456 | } |
1449 | } |
1457 | |
1450 | |
1458 | return 1; |
1451 | return 1; |
1459 | } |
1452 | } |
|
|
1453 | |
1460 | switch (op->type) |
1454 | switch (op->type) |
1461 | { |
1455 | { |
1462 | case SPELL_EFFECT: |
1456 | case SPELL_EFFECT: |
1463 | move_spell_effect (op); |
1457 | move_spell_effect (op); |
1464 | return 1; |
1458 | return 1; |