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

Comparing deliantra/server/server/monster.C (file contents):
Revision 1.13 by root, Tue Dec 12 20:53:03 2006 UTC vs.
Revision 1.21 by root, Sun Jan 14 23:35:04 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
3 3
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
6 7
7 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
8 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
20 21
21 The authors can be reached via e-mail at <crossfire@schmorp.de> 22 The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 23*/
23 24
24#include <global.h> 25#include <global.h>
25#ifndef __CEXTRACT__
26# include <sproto.h> 26#include <sproto.h>
27# include <spells.h> 27#include <spells.h>
28# include <skills.h> 28#include <skills.h>
29#endif
30
31 29
32#define MIN_MON_RADIUS 3 /* minimum monster detection radius */ 30#define MIN_MON_RADIUS 3 /* minimum monster detection radius */
33
34 31
35/* checks npc->enemy and returns that enemy if still valid, 32/* checks npc->enemy and returns that enemy if still valid,
36 * NULL otherwise. 33 * NULL otherwise.
37 * this is map tile aware. 34 * this is map tile aware.
38 * 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
116find_nearest_living_creature (object *npc) 113find_nearest_living_creature (object *npc)
117{ 114{
118 int i, mflags; 115 int i, mflags;
119 sint16 nx, ny; 116 sint16 nx, ny;
120 maptile *m; 117 maptile *m;
121 object *tmp;
122 int search_arr[SIZEOFFREE]; 118 int search_arr[SIZEOFFREE];
123 119
124 get_search_arr (search_arr); 120 get_search_arr (search_arr);
121
125 for (i = 0; i < SIZEOFFREE; i++) 122 for (i = 0; i < SIZEOFFREE; i++)
126 { 123 {
127 /* modified to implement smart searching using search_arr 124 /* modified to implement smart searching using search_arr
128 * guidance array to determine direction of search order 125 * guidance array to determine direction of search order
129 */ 126 */
130 nx = npc->x + freearr_x[search_arr[i]]; 127 nx = npc->x + freearr_x[search_arr[i]];
131 ny = npc->y + freearr_y[search_arr[i]]; 128 ny = npc->y + freearr_y[search_arr[i]];
132 m = npc->map; 129 m = npc->map;
133 130
134 mflags = get_map_flags (m, &m, nx, ny, &nx, &ny); 131 mflags = get_map_flags (m, &m, nx, ny, &nx, &ny);
132
135 if (mflags & P_OUT_OF_MAP) 133 if (mflags & P_OUT_OF_MAP)
136 continue; 134 continue;
137 135
138 if (mflags & P_IS_ALIVE) 136 if (mflags & P_IS_ALIVE)
139 { 137 {
140 tmp = get_map_ob (m, nx, ny); 138 for (object *tmp = m->at (nx, ny).top; tmp; tmp = tmp->below)
141 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)
142 tmp = tmp->above;
143
144 if (!tmp)
145 {
146 LOG (llevDebug, "find_nearest_living_creature: map %s (%d,%d) has is_alive set but did not find a monster?\n",
147 m->path, nx, ny);
148 }
149 else
150 {
151 if (can_see_monsterP (m, nx, ny, i)) 140 if (can_see_monsterP (m, nx, ny, i))
152 return tmp; 141 return tmp;
153 } 142 }
154 } /* is something living on this space */
155 } 143 }
156 return NULL; /* nothing found */ 144
145 return 0;
157} 146}
158 147
159 148
160/* 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
161 * our caller will find the information useful. 150 * our caller will find the information useful.
398 /* 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 */
399 if (!enemy) 388 if (!enemy)
400 { 389 {
401 if (QUERY_FLAG (op, FLAG_ONLY_ATTACK)) 390 if (QUERY_FLAG (op, FLAG_ONLY_ATTACK))
402 { 391 {
403 op->remove ();
404 op->destroy (0); 392 op->destroy ();
405 return 1; 393 return 1;
406 } 394 }
407 395
408 /* Probably really a bug for a creature to have both 396 /* Probably really a bug for a creature to have both
409 * stand still and a movement type set. 397 * stand still and a movement type set.
458 } /* stand still */ 446 } /* stand still */
459 return 0; 447 return 0;
460 } /* no enemy */ 448 } /* no enemy */
461 449
462 /* We have an enemy. Block immediately below is for pets */ 450 /* We have an enemy. Block immediately below is for pets */
463 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))
464 return follow_owner (op, owner); 452 return follow_owner (op, owner);
465 453
466 /* doppleganger code to change monster facing to that of the nearest 454 /* doppleganger code to change monster facing to that of the nearest
467 * 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
468 * arch set uses it. 456 * arch set uses it.
668 return 1; 656 return 1;
669 657
670 if (QUERY_FLAG (op, FLAG_ONLY_ATTACK)) 658 if (QUERY_FLAG (op, FLAG_ONLY_ATTACK))
671 { 659 {
672 op->remove (); 660 op->remove ();
673 op->destroy (0); 661 op->destroy ();
674 return 1; 662 return 1;
675 } 663 }
676 return 0; 664 return 0;
677} 665}
678 666
789 * other monsters) 777 * other monsters)
790 */ 778 */
791 if (!(dir = path_to_player (part, pl, 0))) 779 if (!(dir = path_to_player (part, pl, 0)))
792 return 0; 780 return 0;
793 781
794 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = get_owner (head)) != NULL) 782 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL)
795 { 783 {
796 get_rangevector (head, owner, &rv1, 0x1); 784 get_rangevector (head, owner, &rv1, 0x1);
797 if (dirdiff (dir, rv1.direction) < 2) 785 if (dirdiff (dir, rv1.direction) < 2)
798 { 786 {
799 return 0; /* Might hit owner with spell */ 787 return 0; /* Might hit owner with spell */
866 * other monsters) 854 * other monsters)
867 */ 855 */
868 if (!(dir = path_to_player (part, pl, 0))) 856 if (!(dir = path_to_player (part, pl, 0)))
869 return 0; 857 return 0;
870 858
871 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = get_owner (head)) != NULL) 859 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL)
872 { 860 {
873 get_rangevector (head, owner, &rv1, 0x1); 861 get_rangevector (head, owner, &rv1, 0x1);
874 if (dirdiff (dir, rv1.direction) < 2) 862 if (dirdiff (dir, rv1.direction) < 2)
875 { 863 {
876 return 0; /* Might hit owner with spell */ 864 return 0; /* Might hit owner with spell */
917 object *skill, *owner; 905 object *skill, *owner;
918 906
919 if (!(dir = path_to_player (part, pl, 0))) 907 if (!(dir = path_to_player (part, pl, 0)))
920 return 0; 908 return 0;
921 909
922 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = get_owner (head)) != NULL) 910 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL)
923 { 911 {
924 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);
925 913
926 if (dirdiff (dir, dir2) < 1) 914 if (dirdiff (dir, dir2) < 1)
927 return 0; /* Might hit owner with skill -thrown rocks for example ? */ 915 return 0; /* Might hit owner with skill -thrown rocks for example ? */
961 int at_least_one = 0; 949 int at_least_one = 0;
962 950
963 if (!(dir = path_to_player (part, pl, 0))) 951 if (!(dir = path_to_player (part, pl, 0)))
964 return 0; 952 return 0;
965 953
966 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = get_owner (head)) != NULL) 954 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL)
967 { 955 {
968 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);
969 957
970 if (dirdiff (dir, dir2) < 2) 958 if (dirdiff (dir, dir2) < 2)
971 return 0; /* Might hit owner with spell */ 959 return 0; /* Might hit owner with spell */
988 { 976 {
989 if (wand->arch) 977 if (wand->arch)
990 { 978 {
991 CLEAR_FLAG (wand, FLAG_ANIMATE); 979 CLEAR_FLAG (wand, FLAG_ANIMATE);
992 wand->face = wand->arch->clone.face; 980 wand->face = wand->arch->clone.face;
993 wand->speed = 0; 981 wand->set_speed (0);
994 update_ob_speed (wand);
995 } 982 }
996 } 983 }
997 /* Success */ 984 /* Success */
998 return 1; 985 return 1;
999 } 986 }
1032 if (!(dir = path_to_player (part, pl, 0))) 1019 if (!(dir = path_to_player (part, pl, 0)))
1033 return 0; 1020 return 0;
1034 if (QUERY_FLAG (head, FLAG_CONFUSED)) 1021 if (QUERY_FLAG (head, FLAG_CONFUSED))
1035 dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2); 1022 dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2);
1036 1023
1037 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = get_owner (head)) != NULL) 1024 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL)
1038 { 1025 {
1039 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);
1040 1027
1041 if (dirdiff (dir, dir2) < 1) 1028 if (dirdiff (dir, dir2) < 1)
1042 return 0; /* Might hit owner with arrow */ 1029 return 0; /* Might hit owner with arrow */
1353 /* Don't use it right now */ 1340 /* Don't use it right now */
1354 return; 1341 return;
1355 } 1342 }
1356 else if (item->type == WEAPON) 1343 else if (item->type == WEAPON)
1357 flag = check_good_weapon (mon, item); 1344 flag = check_good_weapon (mon, item);
1358 else if (IS_ARMOR (item)) 1345 else if (item->is_armor ())
1359 flag = check_good_armour (mon, item); 1346 flag = check_good_armour (mon, item);
1360 /* 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 */
1361 else if (item->type == RING) 1348 else if (item->type == RING)
1362 flag = 1; 1349 flag = 1;
1363 else if (item->type == WAND || item->type == ROD || item->type == HORN) 1350 else if (item->type == WAND || item->type == ROD || item->type == HORN)
1434 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy); 1421 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1435 /* 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. */
1436 if ((mflags & P_OUT_OF_MAP) || !(mflags & P_IS_ALIVE)) 1423 if ((mflags & P_OUT_OF_MAP) || !(mflags & P_IS_ALIVE))
1437 continue; 1424 continue;
1438 1425
1439 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)
1440 if (QUERY_FLAG (npc, FLAG_ALIVE) && QUERY_FLAG (npc, FLAG_UNAGGRESSIVE)) 1427 if (QUERY_FLAG (npc, FLAG_ALIVE) && QUERY_FLAG (npc, FLAG_UNAGGRESSIVE))
1441 npc->enemy = op->enemy; 1428 npc->enemy = op->enemy;
1442 } 1429 }
1443} 1430}
1444 1431
1611void 1598void
1612check_earthwalls (object *op, maptile *m, int x, int y) 1599check_earthwalls (object *op, maptile *m, int x, int y)
1613{ 1600{
1614 object *tmp; 1601 object *tmp;
1615 1602
1616 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)
1617 { 1604 {
1618 if (tmp->type == EARTHWALL) 1605 if (tmp->type == EARTHWALL)
1619 { 1606 {
1620 hit_player (tmp, op->stats.dam, op, AT_PHYSICAL, 1); 1607 hit_player (tmp, op->stats.dam, op, AT_PHYSICAL, 1);
1621 return; 1608 return;
1626void 1613void
1627check_doors (object *op, maptile *m, int x, int y) 1614check_doors (object *op, maptile *m, int x, int y)
1628{ 1615{
1629 object *tmp; 1616 object *tmp;
1630 1617
1631 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)
1632 { 1619 {
1633 if (tmp->type == DOOR) 1620 if (tmp->type == DOOR)
1634 { 1621 {
1635 hit_player (tmp, 1000, op, AT_PHYSICAL, 1); 1622 hit_player (tmp, 1000, op, AT_PHYSICAL, 1);
1636 return; 1623 return;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines