1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2002 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
6 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * the terms of the Affero GNU General Public License as published by the |
9 | * the terms of the Affero GNU General Public License as published by the |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
11 | * option) any later version. |
11 | * option) any later version. |
… | |
… | |
153 | * Currently, only move_monster calls this function. |
153 | * Currently, only move_monster calls this function. |
154 | * Fix function so that we always make calls to get_rangevector |
154 | * Fix function so that we always make calls to get_rangevector |
155 | * if we have a valid target - function as not doing so in |
155 | * if we have a valid target - function as not doing so in |
156 | * many cases. |
156 | * many cases. |
157 | */ |
157 | */ |
158 | object * |
158 | static object * |
159 | find_enemy (object *npc, rv_vector * rv) |
159 | find_enemy (object *npc, rv_vector * rv) |
160 | { |
160 | { |
161 | object *attacker, *tmp = NULL; |
161 | object *attacker, *tmp = NULL; |
162 | |
162 | |
163 | attacker = npc->attacked_by; /* save this for later use. This can be a attacker. */ |
163 | attacker = npc->attacked_by; /* save this for later use. This can be a attacker. */ |
… | |
… | |
231 | /* Sees if this monster should wake up. |
231 | /* Sees if this monster should wake up. |
232 | * Currently, this is only called from move_monster, and |
232 | * Currently, this is only called from move_monster, and |
233 | * if enemy is set, then so should be rv. |
233 | * if enemy is set, then so should be rv. |
234 | * returns 1 if the monster should wake up, 0 otherwise. |
234 | * returns 1 if the monster should wake up, 0 otherwise. |
235 | */ |
235 | */ |
236 | int |
236 | static int |
237 | check_wakeup (object *op, object *enemy, rv_vector *rv) |
237 | check_wakeup (object *op, object *enemy, rv_vector *rv) |
238 | { |
238 | { |
239 | /* Trim work - if no enemy, no need to do anything below */ |
239 | /* Trim work - if no enemy, no need to do anything below */ |
240 | if (!enemy) |
240 | if (!enemy) |
241 | return 0; |
241 | return 0; |
… | |
… | |
272 | } |
272 | } |
273 | |
273 | |
274 | return 0; |
274 | return 0; |
275 | } |
275 | } |
276 | |
276 | |
277 | int |
277 | static int |
278 | move_randomly (object *op) |
278 | move_randomly (object *op) |
279 | { |
279 | { |
280 | /* Give up to 15 chances for a monster to move randomly */ |
280 | /* Give up to 15 chances for a monster to move randomly */ |
281 | for (int i = 0; i < 15; i++) |
281 | for (int i = 0; i < 15; i++) |
282 | if (move_object (op, rndm (8) + 1)) |
282 | if (op->move (rndm (8) + 1)) |
283 | return 1; |
283 | return 1; |
284 | |
284 | |
285 | return 0; |
285 | return 0; |
286 | } |
286 | } |
287 | |
287 | |
… | |
… | |
403 | next = tmp->below; |
403 | next = tmp->below; |
404 | if (monster_can_pick (monster, tmp)) |
404 | if (monster_can_pick (monster, tmp)) |
405 | { |
405 | { |
406 | tmp->remove (); |
406 | tmp->remove (); |
407 | tmp = insert_ob_in_ob (tmp, monster); |
407 | tmp = insert_ob_in_ob (tmp, monster); |
408 | (void) monster_check_apply (monster, tmp); |
408 | monster_check_apply (monster, tmp); |
409 | } |
409 | } |
|
|
410 | |
410 | /* We could try to re-establish the cycling, of the space, but probably |
411 | /* We could try to re-establish the cycling, of the space, but probably |
411 | * not a big deal to just bail out. |
412 | * not a big deal to just bail out. |
412 | */ |
413 | */ |
413 | if (next && next->destroyed ()) |
414 | if (next && next->destroyed ()) |
414 | return; |
415 | return; |
… | |
… | |
785 | static int circle[12] = { 3, 3, 4, 5, 5, 6, 7, 7, 8, 1, 1, 2 }; |
786 | static int circle[12] = { 3, 3, 4, 5, 5, 6, 7, 7, 8, 1, 1, 2 }; |
786 | |
787 | |
787 | if (++ob->move_status > 11) |
788 | if (++ob->move_status > 11) |
788 | ob->move_status = 0; |
789 | ob->move_status = 0; |
789 | |
790 | |
790 | if (!(move_object (ob, circle[ob->move_status]))) |
791 | if (!(ob->move (circle[ob->move_status]))) |
791 | move_object (ob, rndm (8) + 1); |
792 | ob->move (rndm (8) + 1); |
792 | } |
793 | } |
793 | |
794 | |
794 | static void |
795 | static void |
795 | circ2_move (object *ob) |
796 | circ2_move (object *ob) |
796 | { |
797 | { |
797 | static int circle[20] = { 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 1, 1, 1, 2, 2 }; |
798 | static int circle[20] = { 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 1, 1, 1, 2, 2 }; |
798 | |
799 | |
799 | if (++ob->move_status > 19) |
800 | if (++ob->move_status > 19) |
800 | ob->move_status = 0; |
801 | ob->move_status = 0; |
801 | |
802 | |
802 | if (!(move_object (ob, circle[ob->move_status]))) |
803 | if (!(ob->move (circle[ob->move_status]))) |
803 | move_object (ob, rndm (8) + 1); |
804 | ob->move (rndm (8) + 1); |
804 | } |
805 | } |
805 | |
806 | |
806 | static void |
807 | static void |
807 | pace_movev (object *ob) |
808 | pace_movev (object *ob) |
808 | { |
809 | { |
809 | if (ob->move_status++ > 6) |
810 | if (ob->move_status++ > 6) |
810 | ob->move_status = 0; |
811 | ob->move_status = 0; |
811 | |
812 | |
812 | if (ob->move_status < 4) |
813 | if (ob->move_status < 4) |
813 | move_object (ob, 5); |
814 | ob->move (5); |
814 | else |
815 | else |
815 | move_object (ob, 1); |
816 | ob->move (1); |
816 | } |
817 | } |
817 | |
818 | |
818 | static void |
819 | static void |
819 | pace_moveh (object *ob) |
820 | pace_moveh (object *ob) |
820 | { |
821 | { |
821 | if (ob->move_status++ > 6) |
822 | if (ob->move_status++ > 6) |
822 | ob->move_status = 0; |
823 | ob->move_status = 0; |
823 | |
824 | |
824 | if (ob->move_status < 4) |
825 | if (ob->move_status < 4) |
825 | move_object (ob, 3); |
826 | ob->move (3); |
826 | else |
827 | else |
827 | move_object (ob, 7); |
828 | ob->move (7); |
828 | } |
829 | } |
829 | |
830 | |
830 | static void |
831 | static void |
831 | pace2_movev (object *ob) |
832 | pace2_movev (object *ob) |
832 | { |
833 | { |
833 | if (ob->move_status++ > 16) |
834 | if (ob->move_status++ > 16) |
834 | ob->move_status = 0; |
835 | ob->move_status = 0; |
835 | |
836 | |
836 | if (ob->move_status < 6) |
837 | if (ob->move_status < 6) |
837 | move_object (ob, 5); |
838 | ob->move (5); |
838 | else if (ob->move_status < 8) |
839 | else if (ob->move_status < 8) |
839 | return; |
840 | return; |
840 | else if (ob->move_status < 13) |
841 | else if (ob->move_status < 13) |
841 | move_object (ob, 1); |
842 | ob->move (1); |
842 | else |
843 | else |
843 | return; |
844 | return; |
844 | } |
845 | } |
845 | |
846 | |
846 | static void |
847 | static void |
… | |
… | |
848 | { |
849 | { |
849 | if (ob->move_status++ > 16) |
850 | if (ob->move_status++ > 16) |
850 | ob->move_status = 0; |
851 | ob->move_status = 0; |
851 | |
852 | |
852 | if (ob->move_status < 6) |
853 | if (ob->move_status < 6) |
853 | move_object (ob, 3); |
854 | ob->move (3); |
854 | else if (ob->move_status < 8) |
855 | else if (ob->move_status < 8) |
855 | return; |
856 | return; |
856 | else if (ob->move_status < 13) |
857 | else if (ob->move_status < 13) |
857 | move_object (ob, 7); |
858 | ob->move (7); |
858 | else |
859 | else |
859 | return; |
860 | return; |
860 | } |
861 | } |
861 | |
862 | |
862 | static void |
863 | static void |
863 | rand_move (object *ob) |
864 | rand_move (object *ob) |
864 | { |
865 | { |
865 | if (ob->move_status < 1 || ob->move_status > 8 || !(move_object (ob, ob->move_status || !(rndm (9))))) |
866 | if (ob->move_status < 1 || ob->move_status > 8 || !(ob->move (ob->move_status || !(rndm (9))))) |
866 | for (int i = 0; i < 5; i++) |
867 | for (int i = 0; i < 5; i++) |
867 | if (move_object (ob, ob->move_status = rndm (8) + 1)) |
868 | if (ob->move (ob->move_status = rndm (8) + 1)) |
868 | return; |
869 | return; |
869 | } |
870 | } |
870 | |
871 | |
871 | #define MAX_KNOWN_SPELLS 20 |
872 | #define MAX_KNOWN_SPELLS 20 |
872 | |
873 | |
873 | /* Returns a randomly selected spell. This logic is still |
874 | /* Returns a randomly selected spell. This logic is still |
874 | * less than ideal. This code also only seems to deal with |
875 | * less than ideal. This code also only seems to deal with |
875 | * wizard spells, as the check is against sp, and not grace. |
876 | * wizard spells, as the check is against sp, and not grace. |
876 | * can mosnters know cleric spells? |
877 | * can mosnters know cleric spells? |
877 | */ |
878 | */ |
878 | object * |
879 | static object * |
879 | monster_choose_random_spell (object *monster) |
880 | monster_choose_random_spell (object *monster) |
880 | { |
881 | { |
881 | object *altern[MAX_KNOWN_SPELLS]; |
882 | object *altern[MAX_KNOWN_SPELLS]; |
882 | int i = 0; |
883 | int i = 0; |
883 | |
884 | |
… | |
… | |
906 | * part is the part of the monster we are checking against. |
907 | * part is the part of the monster we are checking against. |
907 | * pl is the target. |
908 | * pl is the target. |
908 | * dir is the direction to case. |
909 | * dir is the direction to case. |
909 | * rv is the vector which describes where the enemy is. |
910 | * rv is the vector which describes where the enemy is. |
910 | */ |
911 | */ |
911 | int |
912 | static int |
912 | monster_cast_spell (object *head, object *part, object *pl, int dir, rv_vector * rv) |
913 | monster_cast_spell (object *head, object *part, object *pl, int dir, rv_vector * rv) |
913 | { |
914 | { |
914 | object *spell_item; |
915 | object *spell_item; |
915 | object *owner; |
916 | object *owner; |
916 | rv_vector rv1; |
917 | rv_vector rv1; |
… | |
… | |
982 | head->spellitem = NULL; |
983 | head->spellitem = NULL; |
983 | |
984 | |
984 | return cast_spell (part, part, dir, spell_item, NULL); |
985 | return cast_spell (part, part, dir, spell_item, NULL); |
985 | } |
986 | } |
986 | |
987 | |
987 | int |
988 | static int |
988 | monster_use_scroll (object *head, object *part, object *pl, int dir, rv_vector * rv) |
989 | monster_use_scroll (object *head, object *part, object *pl, int dir, rv_vector * rv) |
989 | { |
990 | { |
990 | object *scroll; |
991 | object *scroll; |
991 | object *owner; |
992 | object *owner; |
992 | rv_vector rv1; |
993 | rv_vector rv1; |
… | |
… | |
1040 | * The skills we are treating here are all but those. -b.t. |
1041 | * The skills we are treating here are all but those. -b.t. |
1041 | * |
1042 | * |
1042 | * At the moment this is only useful for throwing, perhaps for |
1043 | * At the moment this is only useful for throwing, perhaps for |
1043 | * stealing. TODO: This should be more integrated in the game. -MT, 25.11.01 |
1044 | * stealing. TODO: This should be more integrated in the game. -MT, 25.11.01 |
1044 | */ |
1045 | */ |
1045 | int |
1046 | static int |
1046 | monster_use_skill (object *head, object *part, object *pl, int dir) |
1047 | monster_use_skill (object *head, object *part, object *pl, int dir) |
1047 | { |
1048 | { |
1048 | object *skill, *owner; |
1049 | object *skill, *owner; |
1049 | |
1050 | |
1050 | if (!(dir = path_to_player (part, pl, 0))) |
1051 | if (!(dir = path_to_player (part, pl, 0))) |
… | |
… | |
1059 | } |
1060 | } |
1060 | |
1061 | |
1061 | if (QUERY_FLAG (head, FLAG_CONFUSED)) |
1062 | if (QUERY_FLAG (head, FLAG_CONFUSED)) |
1062 | dir = absdir (dir + rndm (3) + rndm (3) - 2); |
1063 | dir = absdir (dir + rndm (3) + rndm (3) - 2); |
1063 | |
1064 | |
|
|
1065 | object *new_skill = 0; |
|
|
1066 | |
1064 | /* skill selection - monster will use the next unused skill. |
1067 | // skill selection - monster will use the last unused skill |
1065 | * well...the following scenario will allow the monster to |
1068 | // and rotate, eventually cycling through all skills. |
1066 | * toggle between 2 skills. One day it would be nice to make |
|
|
1067 | * more skills available to monsters. |
|
|
1068 | */ |
|
|
1069 | for (skill = head->inv; skill; skill = skill->below) |
1069 | for (skill = head->inv; skill; skill = skill->below) |
1070 | if (skill->type == SKILL && skill != head->chosen_skill) |
1070 | if (skill->type == SKILL && skill != head->chosen_skill) |
1071 | { |
1071 | new_skill = skill; |
|
|
1072 | |
|
|
1073 | if (new_skill) |
1072 | head->chosen_skill = skill; |
1074 | splay (head->chosen_skill = new_skill); |
1073 | break; |
|
|
1074 | } |
|
|
1075 | |
|
|
1076 | if (!skill && !head->chosen_skill) |
1075 | else if (!head->chosen_skill) |
1077 | { |
1076 | { |
1078 | LOG (llevDebug, "Error: Monster %s (%d) has FLAG_READY_SKILL without skill.\n", &head->name, head->count); |
1077 | LOG (llevDebug, "Error: Monster %s (%d) has FLAG_READY_SKILL without skill.\n", &head->name, head->count); |
1079 | CLEAR_FLAG (head, FLAG_READY_SKILL); |
1078 | CLEAR_FLAG (head, FLAG_READY_SKILL); |
1080 | return 0; |
1079 | return 0; |
1081 | } |
1080 | } |
… | |
… | |
1083 | /* use skill */ |
1082 | /* use skill */ |
1084 | return do_skill (head, part, head->chosen_skill, dir, NULL); |
1083 | return do_skill (head, part, head->chosen_skill, dir, NULL); |
1085 | } |
1084 | } |
1086 | |
1085 | |
1087 | /* Monster will use a ranged spell attack. */ |
1086 | /* Monster will use a ranged spell attack. */ |
1088 | int |
1087 | static int |
1089 | monster_use_range (object *head, object *part, object *pl, int dir) |
1088 | monster_use_range (object *head, object *part, object *pl, int dir) |
1090 | { |
1089 | { |
1091 | object *wand, *owner; |
1090 | object *wand, *owner; |
1092 | int at_least_one = 0; |
1091 | int at_least_one = 0; |
1093 | |
1092 | |
… | |
… | |
1130 | } |
1129 | } |
1131 | else if (wand->type == ROD || wand->type == HORN) |
1130 | else if (wand->type == ROD || wand->type == HORN) |
1132 | { |
1131 | { |
1133 | /* Found rod/horn, let's use it if possible */ |
1132 | /* Found rod/horn, let's use it if possible */ |
1134 | at_least_one = 1; |
1133 | at_least_one = 1; |
1135 | if (wand->stats.hp < MAX (wand->inv->stats.sp, wand->inv->stats.grace)) |
1134 | if (wand->stats.hp < max (wand->inv->stats.sp, wand->inv->stats.grace)) |
1136 | continue; |
1135 | continue; |
1137 | |
1136 | |
1138 | /* drain charge before casting spell - can be a case where the |
1137 | /* drain charge before casting spell - can be a case where the |
1139 | * spell destroys the monster, and rod, so if done after, results |
1138 | * spell destroys the monster, and rod, so if done after, results |
1140 | * in crash. |
1139 | * in crash. |
… | |
… | |
1153 | LOG (llevError, "Error: Monster %s (%d) HAS_READY_RANGE() without wand/horn/rod.\n", &head->name, head->count); |
1152 | LOG (llevError, "Error: Monster %s (%d) HAS_READY_RANGE() without wand/horn/rod.\n", &head->name, head->count); |
1154 | CLEAR_FLAG (head, FLAG_READY_RANGE); |
1153 | CLEAR_FLAG (head, FLAG_READY_RANGE); |
1155 | return 0; |
1154 | return 0; |
1156 | } |
1155 | } |
1157 | |
1156 | |
1158 | int |
1157 | static int |
1159 | monster_use_bow (object *head, object *part, object *pl, int dir) |
1158 | monster_use_bow (object *head, object *part, object *pl, int dir) |
1160 | { |
1159 | { |
1161 | object *owner; |
1160 | object *owner; |
1162 | |
1161 | |
1163 | if (!(dir = path_to_player (part, pl, 0))) |
1162 | if (!(dir = path_to_player (part, pl, 0))) |
… | |
… | |
1180 | } |
1179 | } |
1181 | |
1180 | |
1182 | void |
1181 | void |
1183 | npc_call_help (object *op) |
1182 | npc_call_help (object *op) |
1184 | { |
1183 | { |
1185 | unordered_mapwalk (op, -7, -7, 7, 7) |
1184 | unordered_mapwalk (mapwalk_buf, op, -7, -7, 7, 7) |
1186 | { |
1185 | { |
1187 | mapspace &ms = m->at (nx, ny); |
1186 | mapspace &ms = m->at (nx, ny); |
1188 | |
1187 | |
1189 | /* If nothing alive on this space, no need to search the space. */ |
1188 | /* If nothing alive on this space, no need to search the space. */ |
1190 | if (!(ms.flags () & P_IS_ALIVE)) |
1189 | if (!(ms.flags () & P_IS_ALIVE)) |
… | |
… | |
1292 | * |
1291 | * |
1293 | * Cast to sint32 before comparing to maxhp since otherwise an (sint16) |
1292 | * Cast to sint32 before comparing to maxhp since otherwise an (sint16) |
1294 | * overflow might produce monsters with negative hp. |
1293 | * overflow might produce monsters with negative hp. |
1295 | */ |
1294 | */ |
1296 | |
1295 | |
1297 | op->last_heal += (int) ((float) (8 * op->stats.Con) / FABS (op->speed)); |
1296 | op->last_heal += (int) ((float) (8 * op->stats.Con) / op->speed); |
1298 | op->stats.hp = MIN ((sint32) op->stats.hp + op->last_heal / 32, op->stats.maxhp); /* causes Con/4 hp/tick */ |
1297 | op->stats.hp = min ((sint32) op->stats.hp + op->last_heal / 32, op->stats.maxhp); /* causes Con/4 hp/tick */ |
1299 | op->last_heal %= 32; |
1298 | op->last_heal %= 32; |
1300 | |
1299 | |
1301 | /* So if the monster has gained enough HP that they are no longer afraid */ |
1300 | /* So if the monster has gained enough HP that they are no longer afraid */ |
1302 | if (QUERY_FLAG (op, FLAG_RUN_AWAY) && op->stats.hp >= (signed short)(((float)op->run_away / 100.f) * (float)op->stats.maxhp)) |
1301 | if (QUERY_FLAG (op, FLAG_RUN_AWAY) && op->stats.hp >= (signed short)(((float)op->run_away / 100.f) * (float)op->stats.maxhp)) |
1303 | CLEAR_FLAG (op, FLAG_RUN_AWAY); |
1302 | CLEAR_FLAG (op, FLAG_RUN_AWAY); |
… | |
… | |
1316 | * |
1315 | * |
1317 | * Cast to sint32 before comparing to maxhp since otherwise an (sint16) |
1316 | * Cast to sint32 before comparing to maxhp since otherwise an (sint16) |
1318 | * overflow might produce monsters with negative sp. |
1317 | * overflow might produce monsters with negative sp. |
1319 | */ |
1318 | */ |
1320 | |
1319 | |
1321 | op->last_sp += (int) ((float) (8 * op->stats.Pow) / fabsf (op->speed)); |
1320 | op->last_sp += (int) ((float) (8 * op->stats.Pow) / op->speed); |
1322 | op->stats.sp = min (op->stats.sp + op->last_sp / 128, op->stats.maxsp); /* causes Pow/16 sp/tick */ |
1321 | op->stats.sp = min (op->stats.sp + op->last_sp / 128, op->stats.maxsp); /* causes Pow/16 sp/tick */ |
1323 | op->last_sp %= 128; |
1322 | op->last_sp %= 128; |
1324 | } |
1323 | } |
1325 | |
1324 | |
1326 | /* this should probably get modified by many more values. |
1325 | /* this should probably get modified by many more values. |
… | |
… | |
1522 | dir = sdir; |
1521 | dir = sdir; |
1523 | else if (smell) |
1522 | else if (smell) |
1524 | { |
1523 | { |
1525 | // no better smell found, so assume the player jumped, and erase this smell |
1524 | // no better smell found, so assume the player jumped, and erase this smell |
1526 | //printf ("erasing smell %d\n", op->ms ().smell);//D |
1525 | //printf ("erasing smell %d\n", op->ms ().smell);//D |
1527 | unordered_mapwalk (op, -1, -1, 1, 1) |
1526 | unordered_mapwalk (mapwalk_buf, op, -1, -1, 1, 1) |
1528 | m->at (nx, ny).smell = 0; |
1527 | m->at (nx, ny).smell = 0; |
1529 | } |
1528 | } |
1530 | } |
1529 | } |
1531 | |
1530 | |
1532 | //+GPL |
1531 | //+GPL |
… | |
… | |
1579 | if (!dir) |
1578 | if (!dir) |
1580 | return 0; |
1579 | return 0; |
1581 | |
1580 | |
1582 | if (!QUERY_FLAG (op, FLAG_STAND_STILL)) |
1581 | if (!QUERY_FLAG (op, FLAG_STAND_STILL)) |
1583 | { |
1582 | { |
1584 | if (move_object (op, dir)) /* Can the monster move directly toward player? */ |
1583 | if (op->move (dir)) /* Can the monster move directly toward player? */ |
1585 | { |
1584 | { |
1586 | /* elmex: Turn our monster after it moved if it has DISTATT attack */ |
1585 | /* elmex: Turn our monster after it moved if it has DISTATT attack */ |
1587 | if ((op->attack_movement & LO4) == DISTATT) |
1586 | if ((op->attack_movement & LO4) == DISTATT) |
1588 | op->direction = pre_att_dir; |
1587 | op->direction = pre_att_dir; |
1589 | |
1588 | |
… | |
… | |
1598 | for (diff = 1; diff <= maxdiff; diff++) |
1597 | for (diff = 1; diff <= maxdiff; diff++) |
1599 | { |
1598 | { |
1600 | /* try different detours */ |
1599 | /* try different detours */ |
1601 | int m = 1 - rndm (2) * 2; /* Try left or right first? */ |
1600 | int m = 1 - rndm (2) * 2; /* Try left or right first? */ |
1602 | |
1601 | |
1603 | if (move_object (op, absdir (dir + diff * m)) || move_object (op, absdir (dir - diff * m))) |
1602 | if (op->move (absdir (dir + diff * m)) || op->move (absdir (dir - diff * m))) |
1604 | return 0; |
1603 | return 0; |
1605 | } |
1604 | } |
1606 | } |
1605 | } |
1607 | } /* if monster is not standing still */ |
1606 | } /* if monster is not standing still */ |
1608 | |
1607 | |
… | |
… | |
1839 | |
1838 | |
1840 | if (op->glow_radius > 0) |
1839 | if (op->glow_radius > 0) |
1841 | return 1; |
1840 | return 1; |
1842 | |
1841 | |
1843 | if (op->map) |
1842 | if (op->map) |
1844 | unordered_mapwalk (op, -MAX_LIGHT_RADIUS, -MAX_LIGHT_RADIUS, MAX_LIGHT_RADIUS, MAX_LIGHT_RADIUS) |
1843 | unordered_mapwalk (mapwalk_buf, op, -MAX_LIGHT_RADIUS, -MAX_LIGHT_RADIUS, MAX_LIGHT_RADIUS, MAX_LIGHT_RADIUS) |
1845 | { |
1844 | { |
1846 | /* Check the spaces with the max light radius to see if any of them |
1845 | /* Check the spaces with the max light radius to see if any of them |
1847 | * have lights, and if any of them light the player enough, then return 1. |
1846 | * have lights, and if any of them light the player enough, then return 1. |
1848 | */ |
1847 | */ |
1849 | int light = m->at (nx, ny).light; |
1848 | int light = m->at (nx, ny).light; |