1 | |
|
|
2 | /* |
|
|
3 | * static char *rcsid_monster_c = |
|
|
4 | * "$Id: monster.C,v 1.8 2006/09/10 15:59:57 root Exp $"; |
|
|
5 | */ |
|
|
6 | |
|
|
7 | /* |
1 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
2 | CrossFire, A Multiplayer game for X-windows |
9 | |
3 | |
|
|
4 | Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team |
10 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
5 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
11 | Copyright (C) 1992 Frank Tore Johansen |
6 | Copyright (C) 1992 Frank Tore Johansen |
12 | |
7 | |
13 | This program is free software; you can redistribute it and/or modify |
8 | This program is free software; you can redistribute it and/or modify |
14 | it under the terms of the GNU General Public License as published by |
9 | it under the terms of the GNU General Public License as published by |
… | |
… | |
22 | |
17 | |
23 | You should have received a copy of the GNU General Public License |
18 | You should have received a copy of the GNU General Public License |
24 | along with this program; if not, write to the Free Software |
19 | along with this program; if not, write to the Free Software |
25 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | |
21 | |
27 | The authors can be reached via e-mail at crossfire-devel@real-time.com |
22 | The authors can be reached via e-mail at <crossfire@schmorp.de> |
28 | */ |
23 | */ |
29 | |
24 | |
30 | #include <global.h> |
25 | #include <global.h> |
31 | #ifndef __CEXTRACT__ |
|
|
32 | # include <sproto.h> |
26 | #include <sproto.h> |
33 | # include <spells.h> |
27 | #include <spells.h> |
34 | # include <skills.h> |
28 | #include <skills.h> |
35 | #endif |
|
|
36 | |
|
|
37 | |
29 | |
38 | #define MIN_MON_RADIUS 3 /* minimum monster detection radius */ |
30 | #define MIN_MON_RADIUS 3 /* minimum monster detection radius */ |
39 | |
|
|
40 | |
31 | |
41 | /* checks npc->enemy and returns that enemy if still valid, |
32 | /* checks npc->enemy and returns that enemy if still valid, |
42 | * NULL otherwise. |
33 | * NULL otherwise. |
43 | * this is map tile aware. |
34 | * this is map tile aware. |
44 | * If this returns an enemy, the range vector rv should also be |
35 | * If this returns an enemy, the range vector rv should also be |
… | |
… | |
121 | object * |
112 | object * |
122 | find_nearest_living_creature (object *npc) |
113 | find_nearest_living_creature (object *npc) |
123 | { |
114 | { |
124 | int i, mflags; |
115 | int i, mflags; |
125 | sint16 nx, ny; |
116 | sint16 nx, ny; |
126 | mapstruct *m; |
117 | maptile *m; |
127 | object *tmp; |
|
|
128 | int search_arr[SIZEOFFREE]; |
118 | int search_arr[SIZEOFFREE]; |
129 | |
119 | |
130 | get_search_arr (search_arr); |
120 | get_search_arr (search_arr); |
|
|
121 | |
131 | for (i = 0; i < SIZEOFFREE; i++) |
122 | for (i = 0; i < SIZEOFFREE; i++) |
132 | { |
123 | { |
133 | /* modified to implement smart searching using search_arr |
124 | /* modified to implement smart searching using search_arr |
134 | * guidance array to determine direction of search order |
125 | * guidance array to determine direction of search order |
135 | */ |
126 | */ |
136 | nx = npc->x + freearr_x[search_arr[i]]; |
127 | nx = npc->x + freearr_x[search_arr[i]]; |
137 | ny = npc->y + freearr_y[search_arr[i]]; |
128 | ny = npc->y + freearr_y[search_arr[i]]; |
138 | m = npc->map; |
129 | m = npc->map; |
139 | |
130 | |
140 | mflags = get_map_flags (m, &m, nx, ny, &nx, &ny); |
131 | mflags = get_map_flags (m, &m, nx, ny, &nx, &ny); |
|
|
132 | |
141 | if (mflags & P_OUT_OF_MAP) |
133 | if (mflags & P_OUT_OF_MAP) |
142 | continue; |
134 | continue; |
143 | |
135 | |
144 | if (mflags & P_IS_ALIVE) |
136 | if (mflags & P_IS_ALIVE) |
145 | { |
137 | { |
146 | tmp = get_map_ob (m, nx, ny); |
138 | for (object *tmp = m->at (nx, ny).top; tmp; tmp = tmp->below) |
147 | while (tmp != NULL && !QUERY_FLAG (tmp, FLAG_MONSTER) && !QUERY_FLAG (tmp, FLAG_GENERATOR) && tmp->type != PLAYER) |
139 | if (tmp->flag [FLAG_MONSTER] || tmp->flag [FLAG_GENERATOR] || tmp->type == PLAYER) |
148 | tmp = tmp->above; |
|
|
149 | |
|
|
150 | if (!tmp) |
|
|
151 | { |
|
|
152 | LOG (llevDebug, "find_nearest_living_creature: map %s (%d,%d) has is_alive set but did not find a monster?\n", |
|
|
153 | m->path, nx, ny); |
|
|
154 | } |
|
|
155 | else |
|
|
156 | { |
|
|
157 | if (can_see_monsterP (m, nx, ny, i)) |
140 | if (can_see_monsterP (m, nx, ny, i)) |
158 | return tmp; |
141 | return tmp; |
159 | } |
142 | } |
160 | } /* is something living on this space */ |
|
|
161 | } |
143 | } |
162 | return NULL; /* nothing found */ |
144 | |
|
|
145 | return 0; |
163 | } |
146 | } |
164 | |
147 | |
165 | |
148 | |
166 | /* Tries to find an enmy for npc. We pass the range vector since |
149 | /* Tries to find an enmy for npc. We pass the range vector since |
167 | * our caller will find the information useful. |
150 | * our caller will find the information useful. |
… | |
… | |
175 | find_enemy (object *npc, rv_vector * rv) |
158 | find_enemy (object *npc, rv_vector * rv) |
176 | { |
159 | { |
177 | object *attacker, *tmp = NULL; |
160 | object *attacker, *tmp = NULL; |
178 | |
161 | |
179 | attacker = npc->attacked_by; /* save this for later use. This can be a attacker. */ |
162 | attacker = npc->attacked_by; /* save this for later use. This can be a attacker. */ |
180 | npc->attacked_by = NULL; /* always clear the attacker entry */ |
163 | npc->attacked_by = 0; /* always clear the attacker entry */ |
181 | |
164 | |
182 | /* if we berserk, we don't care about others - we attack all we can find */ |
165 | /* if we berserk, we don't care about others - we attack all we can find */ |
183 | if (QUERY_FLAG (npc, FLAG_BERSERK)) |
166 | if (QUERY_FLAG (npc, FLAG_BERSERK)) |
184 | { |
167 | { |
185 | tmp = find_nearest_living_creature (npc); |
168 | tmp = find_nearest_living_creature (npc); |
|
|
169 | |
186 | if (tmp) |
170 | if (tmp) |
187 | get_rangevector (npc, tmp, rv, 0); |
171 | get_rangevector (npc, tmp, rv, 0); |
188 | return tmp; |
172 | return tmp; |
189 | } |
173 | } |
190 | |
174 | |
… | |
… | |
200 | |
184 | |
201 | /* pet move */ |
185 | /* pet move */ |
202 | if ((npc->attack_movement & HI4) == PETMOVE) |
186 | if ((npc->attack_movement & HI4) == PETMOVE) |
203 | { |
187 | { |
204 | tmp = get_pet_enemy (npc, rv); |
188 | tmp = get_pet_enemy (npc, rv); |
|
|
189 | |
205 | if (tmp) |
190 | if (tmp) |
206 | get_rangevector (npc, tmp, rv, 0); |
191 | get_rangevector (npc, tmp, rv, 0); |
|
|
192 | |
207 | return tmp; |
193 | return tmp; |
208 | } |
194 | } |
209 | |
195 | |
210 | /* we check our old enemy. */ |
196 | /* we check our old enemy. */ |
211 | if ((tmp = check_enemy (npc, rv)) == NULL) |
197 | if (!(tmp = check_enemy (npc, rv))) |
212 | { |
198 | { |
213 | if (attacker) /* if we have an attacker, check him */ |
199 | if (attacker) /* if we have an attacker, check him */ |
214 | { |
200 | { |
215 | /* we want be sure this is the right one! */ |
201 | /* TODO: thats not finished */ |
216 | if (attacker->count == npc->attacked_by_count) |
202 | /* we don't want a fight evil vs evil or good against non evil */ |
|
|
203 | |
|
|
204 | if (QUERY_FLAG (npc, FLAG_NEUTRAL) || QUERY_FLAG (attacker, FLAG_NEUTRAL) || /* neutral */ |
|
|
205 | (QUERY_FLAG (npc, FLAG_FRIENDLY) && QUERY_FLAG (attacker, FLAG_FRIENDLY)) || |
|
|
206 | (!QUERY_FLAG (npc, FLAG_FRIENDLY) && (!QUERY_FLAG (attacker, FLAG_FRIENDLY) && attacker->type != PLAYER))) |
|
|
207 | CLEAR_FLAG (npc, FLAG_SLEEP); /* skip it, but lets wakeup */ |
|
|
208 | else if (on_same_map (npc, attacker)) /* thats the only thing we must know... */ |
217 | { |
209 | { |
218 | /* TODO: thats not finished */ |
|
|
219 | /* we don't want a fight evil vs evil or good against non evil */ |
|
|
220 | |
|
|
221 | if (QUERY_FLAG (npc, FLAG_NEUTRAL) || QUERY_FLAG (attacker, FLAG_NEUTRAL) || /* neutral */ |
|
|
222 | (QUERY_FLAG (npc, FLAG_FRIENDLY) && QUERY_FLAG (attacker, FLAG_FRIENDLY)) || |
|
|
223 | (!QUERY_FLAG (npc, FLAG_FRIENDLY) && (!QUERY_FLAG (attacker, FLAG_FRIENDLY) && attacker->type != PLAYER))) |
|
|
224 | CLEAR_FLAG (npc, FLAG_SLEEP); /* skip it, but lets wakeup */ |
|
|
225 | else if (on_same_map (npc, attacker)) /* thats the only thing we must know... */ |
|
|
226 | { |
|
|
227 | CLEAR_FLAG (npc, FLAG_SLEEP); /* well, NOW we really should wake up! */ |
210 | CLEAR_FLAG (npc, FLAG_SLEEP); /* well, NOW we really should wake up! */ |
228 | npc->enemy = attacker; |
211 | npc->enemy = attacker; |
229 | return attacker; /* yes, we face our attacker! */ |
212 | return attacker; /* yes, we face our attacker! */ |
230 | } |
|
|
231 | } |
213 | } |
232 | } |
214 | } |
233 | |
215 | |
234 | /* we have no legal enemy or attacker, so we try to target a new one */ |
216 | /* we have no legal enemy or attacker, so we try to target a new one */ |
235 | if (!QUERY_FLAG (npc, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (npc, FLAG_FRIENDLY) && !QUERY_FLAG (npc, FLAG_NEUTRAL)) |
217 | if (!QUERY_FLAG (npc, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (npc, FLAG_FRIENDLY) && !QUERY_FLAG (npc, FLAG_NEUTRAL)) |
… | |
… | |
326 | oph = oph->head; |
308 | oph = oph->head; |
327 | |
309 | |
328 | if (QUERY_FLAG (op, FLAG_NO_ATTACK)) /* we never ever attack */ |
310 | if (QUERY_FLAG (op, FLAG_NO_ATTACK)) /* we never ever attack */ |
329 | enemy = op->enemy = NULL; |
311 | enemy = op->enemy = NULL; |
330 | else if ((enemy = find_enemy (op, &rv))) |
312 | else if ((enemy = find_enemy (op, &rv))) |
331 | { |
|
|
332 | /* we have an enemy, just tell him we want him dead */ |
313 | /* we have an enemy, just tell him we want him dead */ |
333 | enemy->attacked_by = op; /* our ptr */ |
314 | enemy->attacked_by = op; /* our ptr */ |
334 | enemy->attacked_by_count = op->count; /* our tag */ |
|
|
335 | } |
|
|
336 | |
315 | |
337 | /* generate hp, if applicable */ |
316 | /* generate hp, if applicable */ |
338 | if (op->stats.Con > 0 && op->stats.hp < op->stats.maxhp) |
317 | if (op->stats.Con > 0 && op->stats.hp < op->stats.maxhp) |
339 | { |
318 | { |
340 | |
319 | |
… | |
… | |
408 | /* If we don't have an enemy, do special movement or the like */ |
387 | /* If we don't have an enemy, do special movement or the like */ |
409 | if (!enemy) |
388 | if (!enemy) |
410 | { |
389 | { |
411 | if (QUERY_FLAG (op, FLAG_ONLY_ATTACK)) |
390 | if (QUERY_FLAG (op, FLAG_ONLY_ATTACK)) |
412 | { |
391 | { |
413 | remove_ob (op); |
392 | op->destroy (); |
414 | free_object (op); |
|
|
415 | return 1; |
393 | return 1; |
416 | } |
394 | } |
417 | |
395 | |
418 | /* Probably really a bug for a creature to have both |
396 | /* Probably really a bug for a creature to have both |
419 | * stand still and a movement type set. |
397 | * stand still and a movement type set. |
… | |
… | |
468 | } /* stand still */ |
446 | } /* stand still */ |
469 | return 0; |
447 | return 0; |
470 | } /* no enemy */ |
448 | } /* no enemy */ |
471 | |
449 | |
472 | /* We have an enemy. Block immediately below is for pets */ |
450 | /* We have an enemy. Block immediately below is for pets */ |
473 | if ((op->attack_movement & HI4) == PETMOVE && (owner = get_owner (op)) != NULL && !on_same_map (op, owner)) |
451 | if ((op->attack_movement & HI4) == PETMOVE && (owner = op->owner) != NULL && !on_same_map (op, owner)) |
474 | return follow_owner (op, owner); |
452 | return follow_owner (op, owner); |
475 | |
453 | |
476 | /* doppleganger code to change monster facing to that of the nearest |
454 | /* doppleganger code to change monster facing to that of the nearest |
477 | * player. Hmm. The code is here, but no monster in the current |
455 | * player. Hmm. The code is here, but no monster in the current |
478 | * arch set uses it. |
456 | * arch set uses it. |
… | |
… | |
677 | if (QUERY_FLAG (part, FLAG_FREED)) /* Might be freed by ghost-attack or hit-back */ |
655 | if (QUERY_FLAG (part, FLAG_FREED)) /* Might be freed by ghost-attack or hit-back */ |
678 | return 1; |
656 | return 1; |
679 | |
657 | |
680 | if (QUERY_FLAG (op, FLAG_ONLY_ATTACK)) |
658 | if (QUERY_FLAG (op, FLAG_ONLY_ATTACK)) |
681 | { |
659 | { |
682 | remove_ob (op); |
660 | op->remove (); |
683 | free_object (op); |
661 | op->destroy (); |
684 | return 1; |
662 | return 1; |
685 | } |
663 | } |
686 | return 0; |
664 | return 0; |
687 | } |
665 | } |
688 | |
666 | |
… | |
… | |
799 | * other monsters) |
777 | * other monsters) |
800 | */ |
778 | */ |
801 | if (!(dir = path_to_player (part, pl, 0))) |
779 | if (!(dir = path_to_player (part, pl, 0))) |
802 | return 0; |
780 | return 0; |
803 | |
781 | |
804 | if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = get_owner (head)) != NULL) |
782 | if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL) |
805 | { |
783 | { |
806 | get_rangevector (head, owner, &rv1, 0x1); |
784 | get_rangevector (head, owner, &rv1, 0x1); |
807 | if (dirdiff (dir, rv1.direction) < 2) |
785 | if (dirdiff (dir, rv1.direction) < 2) |
808 | { |
786 | { |
809 | return 0; /* Might hit owner with spell */ |
787 | return 0; /* Might hit owner with spell */ |
… | |
… | |
876 | * other monsters) |
854 | * other monsters) |
877 | */ |
855 | */ |
878 | if (!(dir = path_to_player (part, pl, 0))) |
856 | if (!(dir = path_to_player (part, pl, 0))) |
879 | return 0; |
857 | return 0; |
880 | |
858 | |
881 | if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = get_owner (head)) != NULL) |
859 | if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL) |
882 | { |
860 | { |
883 | get_rangevector (head, owner, &rv1, 0x1); |
861 | get_rangevector (head, owner, &rv1, 0x1); |
884 | if (dirdiff (dir, rv1.direction) < 2) |
862 | if (dirdiff (dir, rv1.direction) < 2) |
885 | { |
863 | { |
886 | return 0; /* Might hit owner with spell */ |
864 | return 0; /* Might hit owner with spell */ |
… | |
… | |
927 | object *skill, *owner; |
905 | object *skill, *owner; |
928 | |
906 | |
929 | if (!(dir = path_to_player (part, pl, 0))) |
907 | if (!(dir = path_to_player (part, pl, 0))) |
930 | return 0; |
908 | return 0; |
931 | |
909 | |
932 | if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = get_owner (head)) != NULL) |
910 | if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL) |
933 | { |
911 | { |
934 | int dir2 = find_dir_2 (head->x - owner->x, head->y - owner->y); |
912 | int dir2 = find_dir_2 (head->x - owner->x, head->y - owner->y); |
935 | |
913 | |
936 | if (dirdiff (dir, dir2) < 1) |
914 | if (dirdiff (dir, dir2) < 1) |
937 | return 0; /* Might hit owner with skill -thrown rocks for example ? */ |
915 | return 0; /* Might hit owner with skill -thrown rocks for example ? */ |
… | |
… | |
971 | int at_least_one = 0; |
949 | int at_least_one = 0; |
972 | |
950 | |
973 | if (!(dir = path_to_player (part, pl, 0))) |
951 | if (!(dir = path_to_player (part, pl, 0))) |
974 | return 0; |
952 | return 0; |
975 | |
953 | |
976 | if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = get_owner (head)) != NULL) |
954 | if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL) |
977 | { |
955 | { |
978 | int dir2 = find_dir_2 (head->x - owner->x, head->y - owner->y); |
956 | int dir2 = find_dir_2 (head->x - owner->x, head->y - owner->y); |
979 | |
957 | |
980 | if (dirdiff (dir, dir2) < 2) |
958 | if (dirdiff (dir, dir2) < 2) |
981 | return 0; /* Might hit owner with spell */ |
959 | return 0; /* Might hit owner with spell */ |
… | |
… | |
998 | { |
976 | { |
999 | if (wand->arch) |
977 | if (wand->arch) |
1000 | { |
978 | { |
1001 | CLEAR_FLAG (wand, FLAG_ANIMATE); |
979 | CLEAR_FLAG (wand, FLAG_ANIMATE); |
1002 | wand->face = wand->arch->clone.face; |
980 | wand->face = wand->arch->clone.face; |
1003 | wand->speed = 0; |
981 | wand->set_speed (0); |
1004 | update_ob_speed (wand); |
|
|
1005 | } |
982 | } |
1006 | } |
983 | } |
1007 | /* Success */ |
984 | /* Success */ |
1008 | return 1; |
985 | return 1; |
1009 | } |
986 | } |
… | |
… | |
1042 | if (!(dir = path_to_player (part, pl, 0))) |
1019 | if (!(dir = path_to_player (part, pl, 0))) |
1043 | return 0; |
1020 | return 0; |
1044 | if (QUERY_FLAG (head, FLAG_CONFUSED)) |
1021 | if (QUERY_FLAG (head, FLAG_CONFUSED)) |
1045 | dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2); |
1022 | dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2); |
1046 | |
1023 | |
1047 | if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = get_owner (head)) != NULL) |
1024 | if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL) |
1048 | { |
1025 | { |
1049 | int dir2 = find_dir_2 (head->x - owner->x, head->y - owner->y); |
1026 | int dir2 = find_dir_2 (head->x - owner->x, head->y - owner->y); |
1050 | |
1027 | |
1051 | if (dirdiff (dir, dir2) < 1) |
1028 | if (dirdiff (dir, dir2) < 1) |
1052 | return 0; /* Might hit owner with arrow */ |
1029 | return 0; /* Might hit owner with arrow */ |
… | |
… | |
1157 | |
1134 | |
1158 | void |
1135 | void |
1159 | monster_check_pickup (object *monster) |
1136 | monster_check_pickup (object *monster) |
1160 | { |
1137 | { |
1161 | object *tmp, *next; |
1138 | object *tmp, *next; |
1162 | int next_tag; |
|
|
1163 | |
1139 | |
1164 | for (tmp = monster->below; tmp != NULL; tmp = next) |
1140 | for (tmp = monster->below; tmp != NULL; tmp = next) |
1165 | { |
1141 | { |
1166 | next = tmp->below; |
1142 | next = tmp->below; |
1167 | next_tag = next ? next->count : 0; |
|
|
1168 | if (monster_can_pick (monster, tmp)) |
1143 | if (monster_can_pick (monster, tmp)) |
1169 | { |
1144 | { |
1170 | remove_ob (tmp); |
1145 | tmp->remove (); |
1171 | tmp = insert_ob_in_ob (tmp, monster); |
1146 | tmp = insert_ob_in_ob (tmp, monster); |
1172 | (void) monster_check_apply (monster, tmp); |
1147 | (void) monster_check_apply (monster, tmp); |
1173 | } |
1148 | } |
1174 | /* We could try to re-establish the cycling, of the space, but probably |
1149 | /* We could try to re-establish the cycling, of the space, but probably |
1175 | * not a big deal to just bail out. |
1150 | * not a big deal to just bail out. |
1176 | */ |
1151 | */ |
1177 | if (next && was_destroyed (next, next_tag)) |
1152 | if (next && next->destroyed ()) |
1178 | return; |
1153 | return; |
1179 | } |
1154 | } |
1180 | } |
1155 | } |
1181 | |
1156 | |
1182 | /* |
1157 | /* |
… | |
… | |
1365 | /* Don't use it right now */ |
1340 | /* Don't use it right now */ |
1366 | return; |
1341 | return; |
1367 | } |
1342 | } |
1368 | else if (item->type == WEAPON) |
1343 | else if (item->type == WEAPON) |
1369 | flag = check_good_weapon (mon, item); |
1344 | flag = check_good_weapon (mon, item); |
1370 | else if (IS_ARMOR (item)) |
1345 | else if (item->is_armor ()) |
1371 | flag = check_good_armour (mon, item); |
1346 | flag = check_good_armour (mon, item); |
1372 | /* Should do something more, like make sure this is a better item */ |
1347 | /* Should do something more, like make sure this is a better item */ |
1373 | else if (item->type == RING) |
1348 | else if (item->type == RING) |
1374 | flag = 1; |
1349 | flag = 1; |
1375 | else if (item->type == WAND || item->type == ROD || item->type == HORN) |
1350 | else if (item->type == WAND || item->type == ROD || item->type == HORN) |
… | |
… | |
1433 | npc_call_help (object *op) |
1408 | npc_call_help (object *op) |
1434 | { |
1409 | { |
1435 | int x, y, mflags; |
1410 | int x, y, mflags; |
1436 | object *npc; |
1411 | object *npc; |
1437 | sint16 sx, sy; |
1412 | sint16 sx, sy; |
1438 | mapstruct *m; |
1413 | maptile *m; |
1439 | |
1414 | |
1440 | for (x = -3; x < 4; x++) |
1415 | for (x = -3; x < 4; x++) |
1441 | for (y = -3; y < 4; y++) |
1416 | for (y = -3; y < 4; y++) |
1442 | { |
1417 | { |
1443 | m = op->map; |
1418 | m = op->map; |
… | |
… | |
1446 | mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); |
1421 | mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); |
1447 | /* If nothing alive on this space, no need to search the space. */ |
1422 | /* If nothing alive on this space, no need to search the space. */ |
1448 | if ((mflags & P_OUT_OF_MAP) || !(mflags & P_IS_ALIVE)) |
1423 | if ((mflags & P_OUT_OF_MAP) || !(mflags & P_IS_ALIVE)) |
1449 | continue; |
1424 | continue; |
1450 | |
1425 | |
1451 | for (npc = get_map_ob (m, sx, sy); npc != NULL; npc = npc->above) |
1426 | for (npc = GET_MAP_OB (m, sx, sy); npc != NULL; npc = npc->above) |
1452 | if (QUERY_FLAG (npc, FLAG_ALIVE) && QUERY_FLAG (npc, FLAG_UNAGGRESSIVE)) |
1427 | if (QUERY_FLAG (npc, FLAG_ALIVE) && QUERY_FLAG (npc, FLAG_UNAGGRESSIVE)) |
1453 | npc->enemy = op->enemy; |
1428 | npc->enemy = op->enemy; |
1454 | } |
1429 | } |
1455 | } |
1430 | } |
1456 | |
1431 | |
… | |
… | |
1619 | if (move_object (ob, ob->move_status = RANDOM () % 8 + 1)) |
1594 | if (move_object (ob, ob->move_status = RANDOM () % 8 + 1)) |
1620 | return; |
1595 | return; |
1621 | } |
1596 | } |
1622 | |
1597 | |
1623 | void |
1598 | void |
1624 | check_earthwalls (object *op, mapstruct *m, int x, int y) |
1599 | check_earthwalls (object *op, maptile *m, int x, int y) |
1625 | { |
1600 | { |
1626 | object *tmp; |
1601 | object *tmp; |
1627 | |
1602 | |
1628 | for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above) |
1603 | for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above) |
1629 | { |
1604 | { |
1630 | if (tmp->type == EARTHWALL) |
1605 | if (tmp->type == EARTHWALL) |
1631 | { |
1606 | { |
1632 | hit_player (tmp, op->stats.dam, op, AT_PHYSICAL, 1); |
1607 | hit_player (tmp, op->stats.dam, op, AT_PHYSICAL, 1); |
1633 | return; |
1608 | return; |
1634 | } |
1609 | } |
1635 | } |
1610 | } |
1636 | } |
1611 | } |
1637 | |
1612 | |
1638 | void |
1613 | void |
1639 | check_doors (object *op, mapstruct *m, int x, int y) |
1614 | check_doors (object *op, maptile *m, int x, int y) |
1640 | { |
1615 | { |
1641 | object *tmp; |
1616 | object *tmp; |
1642 | |
1617 | |
1643 | for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above) |
1618 | for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above) |
1644 | { |
1619 | { |
1645 | if (tmp->type == DOOR) |
1620 | if (tmp->type == DOOR) |
1646 | { |
1621 | { |
1647 | hit_player (tmp, 1000, op, AT_PHYSICAL, 1); |
1622 | hit_player (tmp, 1000, op, AT_PHYSICAL, 1); |
1648 | return; |
1623 | return; |
… | |
… | |
1847 | |
1822 | |
1848 | int |
1823 | int |
1849 | stand_in_light (object *op) |
1824 | stand_in_light (object *op) |
1850 | { |
1825 | { |
1851 | sint16 nx, ny; |
1826 | sint16 nx, ny; |
1852 | mapstruct *m; |
1827 | maptile *m; |
1853 | |
1828 | |
1854 | |
1829 | |
1855 | if (!op) |
1830 | if (!op) |
1856 | return 0; |
1831 | return 0; |
1857 | if (op->glow_radius > 0) |
1832 | if (op->glow_radius > 0) |