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.21 by root, Sun Jan 14 23:35:04 2007 UTC vs.
Revision 1.26 by root, Tue Apr 24 12:32:16 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) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
6 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
7 7 *
8 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
9 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
10 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 * (at your option) any later version.
12 12 *
13 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 * GNU General Public License for more details.
17 17 *
18 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
19 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 21 *
22 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>
23*/ 23 */
24 24
25#include <global.h> 25#include <global.h>
26#include <sproto.h> 26#include <sproto.h>
27#include <spells.h> 27#include <spells.h>
28#include <skills.h> 28#include <skills.h>
85 * target enemy - this code below makes sure the enemy is something 85 * target enemy - this code below makes sure the enemy is something
86 * that should be attacked. My guess is that the arrow hits 86 * that should be attacked. My guess is that the arrow hits
87 * the creature/owner, and so the creature then takes that 87 * the creature/owner, and so the creature then takes that
88 * as the enemy to attack. 88 * as the enemy to attack.
89 */ 89 */
90 else if (!QUERY_FLAG (npc->enemy, FLAG_MONSTER) && 90 else if (!QUERY_FLAG (npc->enemy, FLAG_MONSTER)
91 !QUERY_FLAG (npc->enemy, FLAG_GENERATOR) && npc->enemy->type != PLAYER && npc->enemy->type != GOLEM) 91 && !QUERY_FLAG (npc->enemy, FLAG_GENERATOR)
92 && npc->enemy->type != PLAYER
93 && npc->enemy->type != GOLEM)
92 npc->enemy = NULL; 94 npc->enemy = NULL;
93 95
94 } 96 }
95 return can_detect_enemy (npc, npc->enemy, rv) ? npc->enemy : NULL; 97 return can_detect_enemy (npc, npc->enemy, rv) ? npc->enemy : NULL;
96} 98}
278 int i; 280 int i;
279 281
280 /* Give up to 15 chances for a monster to move randomly */ 282 /* Give up to 15 chances for a monster to move randomly */
281 for (i = 0; i < 15; i++) 283 for (i = 0; i < 15; i++)
282 { 284 {
283 if (move_object (op, RANDOM () % 8 + 1)) 285 if (move_object (op, rndm (8) + 1))
284 return 1; 286 return 1;
285 } 287 }
286 return 0; 288 return 0;
287} 289}
288 290
357 } 359 }
358 360
359 /* this should probably get modified by many more values. 361 /* this should probably get modified by many more values.
360 * (eg, creatures resistance to fear, level, etc. ) 362 * (eg, creatures resistance to fear, level, etc. )
361 */ 363 */
362 if (QUERY_FLAG (op, FLAG_SCARED) && !(RANDOM () % 20)) 364 if (QUERY_FLAG (op, FLAG_SCARED) && !(rndm (20)))
363 { 365 {
364 CLEAR_FLAG (op, FLAG_SCARED); /* Time to regain some "guts"... */ 366 CLEAR_FLAG (op, FLAG_SCARED); /* Time to regain some "guts"... */
365 } 367 }
366 368
367 if (INVOKE_OBJECT (MONSTER_MOVE, op, ARG_OBJECT (op->enemy))) 369 if (INVOKE_OBJECT (MONSTER_MOVE, op, ARG_OBJECT (op->enemy)))
446 } /* stand still */ 448 } /* stand still */
447 return 0; 449 return 0;
448 } /* no enemy */ 450 } /* no enemy */
449 451
450 /* We have an enemy. Block immediately below is for pets */ 452 /* We have an enemy. Block immediately below is for pets */
451 if ((op->attack_movement & HI4) == PETMOVE && (owner = op->owner) != NULL && !on_same_map (op, owner)) 453 if ((op->attack_movement & HI4) == PETMOVE
454 && (owner = op->owner) != NULL
455 && !on_same_map (op, owner)
456 && !owner->flag [FLAG_REMOVED])
452 return follow_owner (op, owner); 457 return follow_owner (op, owner);
453 458
454 /* doppleganger code to change monster facing to that of the nearest 459 /* doppleganger code to change monster facing to that of the nearest
455 * player. Hmm. The code is here, but no monster in the current 460 * player. Hmm. The code is here, but no monster in the current
456 * arch set uses it. 461 * arch set uses it.
486 * but that we test above... so can be old code here 491 * but that we test above... so can be old code here
487 */ 492 */
488 if (QUERY_FLAG (op, FLAG_RUN_AWAY)) 493 if (QUERY_FLAG (op, FLAG_RUN_AWAY))
489 dir = absdir (dir + 4); 494 dir = absdir (dir + 4);
490 if (QUERY_FLAG (op, FLAG_CONFUSED)) 495 if (QUERY_FLAG (op, FLAG_CONFUSED))
491 dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2); 496 dir = absdir (dir + rndm (3) + rndm (3) - 2);
492 497
493 if (QUERY_FLAG (op, FLAG_CAST_SPELL) && !(RANDOM () % 3)) 498 if (QUERY_FLAG (op, FLAG_CAST_SPELL) && !(rndm (3)))
494 { 499 {
495 if (monster_cast_spell (op, part, enemy, dir, &rv1)) 500 if (monster_cast_spell (op, part, enemy, dir, &rv1))
496 return 0; 501 return 0;
497 } 502 }
498 503
499 if (QUERY_FLAG (op, FLAG_READY_SCROLL) && !(RANDOM () % 3)) 504 if (QUERY_FLAG (op, FLAG_READY_SCROLL) && !(rndm (3)))
500 { 505 {
501 if (monster_use_scroll (op, part, enemy, dir, &rv1)) 506 if (monster_use_scroll (op, part, enemy, dir, &rv1))
502 return 0; 507 return 0;
503 } 508 }
504 509
505 if (QUERY_FLAG (op, FLAG_READY_RANGE) && !(RANDOM () % 3)) 510 if (QUERY_FLAG (op, FLAG_READY_RANGE) && !(rndm (3)))
506 { 511 {
507 if (monster_use_range (op, part, enemy, dir)) 512 if (monster_use_range (op, part, enemy, dir))
508 return 0; 513 return 0;
509 } 514 }
510 if (QUERY_FLAG (op, FLAG_READY_SKILL) && !(RANDOM () % 3)) 515 if (QUERY_FLAG (op, FLAG_READY_SKILL) && !(rndm (3)))
511 { 516 {
512 if (monster_use_skill (op, rv.part, enemy, rv.direction)) 517 if (monster_use_skill (op, rv.part, enemy, rv.direction))
513 return 0; 518 return 0;
514 } 519 }
515 if (QUERY_FLAG (op, FLAG_READY_BOW) && !(RANDOM () % 2)) 520 if (QUERY_FLAG (op, FLAG_READY_BOW) && !(rndm (2)))
516 { 521 {
517 if (monster_use_bow (op, part, enemy, dir)) 522 if (monster_use_bow (op, part, enemy, dir))
518 return 0; 523 return 0;
519 } 524 }
520 } /* for processing of all parts */ 525 } /* for processing of all parts */
526 531
527 if (QUERY_FLAG (op, FLAG_SCARED) || QUERY_FLAG (op, FLAG_RUN_AWAY)) 532 if (QUERY_FLAG (op, FLAG_SCARED) || QUERY_FLAG (op, FLAG_RUN_AWAY))
528 dir = absdir (dir + 4); 533 dir = absdir (dir + 4);
529 534
530 if (QUERY_FLAG (op, FLAG_CONFUSED)) 535 if (QUERY_FLAG (op, FLAG_CONFUSED))
531 dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2); 536 dir = absdir (dir + rndm (3) + rndm (3) - 2);
532 537
533 pre_att_dir = dir; /* remember the original direction */ 538 pre_att_dir = dir; /* remember the original direction */
534 539
535 if ((op->attack_movement & LO4) && !QUERY_FLAG (op, FLAG_SCARED)) 540 if ((op->attack_movement & LO4) && !QUERY_FLAG (op, FLAG_SCARED))
536 { 541 {
668can_hit (object *ob1, object *ob2, rv_vector * rv) 673can_hit (object *ob1, object *ob2, rv_vector * rv)
669{ 674{
670 object *more; 675 object *more;
671 rv_vector rv1; 676 rv_vector rv1;
672 677
673 if (QUERY_FLAG (ob1, FLAG_CONFUSED) && !(RANDOM () % 3)) 678 if (QUERY_FLAG (ob1, FLAG_CONFUSED) && !(rndm (3)))
674 return 0; 679 return 0;
675 680
676 if (abs (rv->distance_x) < 2 && abs (rv->distance_y) < 2) 681 if (abs (rv->distance_x) < 2 && abs (rv->distance_y) < 2)
677 return 1; 682 return 1;
678 683
787 return 0; /* Might hit owner with spell */ 792 return 0; /* Might hit owner with spell */
788 } 793 }
789 } 794 }
790 795
791 if (QUERY_FLAG (head, FLAG_CONFUSED)) 796 if (QUERY_FLAG (head, FLAG_CONFUSED))
792 dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2); 797 dir = absdir (dir + rndm (3) + rndm (3) - 2);
793 798
794 /* If the monster hasn't already chosen a spell, choose one 799 /* If the monster hasn't already chosen a spell, choose one
795 * I'm not sure if it really make sense to pre-select spells (events 800 * I'm not sure if it really make sense to pre-select spells (events
796 * could be different by the time the monster goes again). 801 * could be different by the time the monster goes again).
797 */ 802 */
864 return 0; /* Might hit owner with spell */ 869 return 0; /* Might hit owner with spell */
865 } 870 }
866 } 871 }
867 872
868 if (QUERY_FLAG (head, FLAG_CONFUSED)) 873 if (QUERY_FLAG (head, FLAG_CONFUSED))
869 dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2); 874 dir = absdir (dir + rndm (3) + rndm (3) - 2);
870 875
871 for (scroll = head->inv; scroll; scroll = scroll->below) 876 for (scroll = head->inv; scroll; scroll = scroll->below)
872 if (scroll->type == SCROLL && monster_should_cast_spell (head, scroll->inv)) 877 if (scroll->type == SCROLL && monster_should_cast_spell (head, scroll->inv))
873 break; 878 break;
874 879
913 918
914 if (dirdiff (dir, dir2) < 1) 919 if (dirdiff (dir, dir2) < 1)
915 return 0; /* Might hit owner with skill -thrown rocks for example ? */ 920 return 0; /* Might hit owner with skill -thrown rocks for example ? */
916 } 921 }
917 if (QUERY_FLAG (head, FLAG_CONFUSED)) 922 if (QUERY_FLAG (head, FLAG_CONFUSED))
918 dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2); 923 dir = absdir (dir + rndm (3) + rndm (3) - 2);
919 924
920 /* skill selection - monster will use the next unused skill. 925 /* skill selection - monster will use the next unused skill.
921 * well...the following scenario will allow the monster to 926 * well...the following scenario will allow the monster to
922 * toggle between 2 skills. One day it would be nice to make 927 * toggle between 2 skills. One day it would be nice to make
923 * more skills available to monsters. 928 * more skills available to monsters.
957 962
958 if (dirdiff (dir, dir2) < 2) 963 if (dirdiff (dir, dir2) < 2)
959 return 0; /* Might hit owner with spell */ 964 return 0; /* Might hit owner with spell */
960 } 965 }
961 if (QUERY_FLAG (head, FLAG_CONFUSED)) 966 if (QUERY_FLAG (head, FLAG_CONFUSED))
962 dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2); 967 dir = absdir (dir + rndm (3) + rndm (3) - 2);
963 968
964 for (wand = head->inv; wand != NULL; wand = wand->below) 969 for (wand = head->inv; wand != NULL; wand = wand->below)
965 { 970 {
966 if (wand->type == WAND) 971 if (wand->type == WAND)
967 { 972 {
1017 object *owner; 1022 object *owner;
1018 1023
1019 if (!(dir = path_to_player (part, pl, 0))) 1024 if (!(dir = path_to_player (part, pl, 0)))
1020 return 0; 1025 return 0;
1021 if (QUERY_FLAG (head, FLAG_CONFUSED)) 1026 if (QUERY_FLAG (head, FLAG_CONFUSED))
1022 dir = absdir (dir + RANDOM () % 3 + RANDOM () % 3 - 2); 1027 dir = absdir (dir + rndm (3) + rndm (3) - 2);
1023 1028
1024 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL) 1029 if (QUERY_FLAG (head, FLAG_FRIENDLY) && (owner = head->owner) != NULL)
1025 { 1030 {
1026 int dir2 = find_dir_2 (head->x - owner->x, head->y - owner->y); 1031 int dir2 = find_dir_2 (head->x - owner->x, head->y - owner->y);
1027 1032
1517{ 1522{
1518 static int circle[12] = { 3, 3, 4, 5, 5, 6, 7, 7, 8, 1, 1, 2 }; 1523 static int circle[12] = { 3, 3, 4, 5, 5, 6, 7, 7, 8, 1, 1, 2 };
1519 if (++ob->move_status > 11) 1524 if (++ob->move_status > 11)
1520 ob->move_status = 0; 1525 ob->move_status = 0;
1521 if (!(move_object (ob, circle[ob->move_status]))) 1526 if (!(move_object (ob, circle[ob->move_status])))
1522 (void) move_object (ob, RANDOM () % 8 + 1); 1527 (void) move_object (ob, rndm (8) + 1);
1523} 1528}
1524 1529
1525void 1530void
1526circ2_move (object *ob) 1531circ2_move (object *ob)
1527{ 1532{
1528 static int circle[20] = { 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 1, 1, 1, 2, 2 }; 1533 static int circle[20] = { 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 1, 1, 1, 2, 2 };
1529 if (++ob->move_status > 19) 1534 if (++ob->move_status > 19)
1530 ob->move_status = 0; 1535 ob->move_status = 0;
1531 if (!(move_object (ob, circle[ob->move_status]))) 1536 if (!(move_object (ob, circle[ob->move_status])))
1532 (void) move_object (ob, RANDOM () % 8 + 1); 1537 (void) move_object (ob, rndm (8) + 1);
1533} 1538}
1534 1539
1535void 1540void
1536pace_movev (object *ob) 1541pace_movev (object *ob)
1537{ 1542{
1587void 1592void
1588rand_move (object *ob) 1593rand_move (object *ob)
1589{ 1594{
1590 int i; 1595 int i;
1591 1596
1592 if (ob->move_status < 1 || ob->move_status > 8 || !(move_object (ob, ob->move_status || !(RANDOM () % 9)))) 1597 if (ob->move_status < 1 || ob->move_status > 8 || !(move_object (ob, ob->move_status || !(rndm (9)))))
1593 for (i = 0; i < 5; i++) 1598 for (i = 0; i < 5; i++)
1594 if (move_object (ob, ob->move_status = RANDOM () % 8 + 1)) 1599 if (move_object (ob, ob->move_status = rndm (8) + 1))
1595 return; 1600 return;
1596} 1601}
1597 1602
1598void 1603void
1599check_earthwalls (object *op, maptile *m, int x, int y) 1604check_earthwalls (object *op, maptile *m, int x, int y)
1644 tmp = op; 1649 tmp = op;
1645 1650
1646 /* New throw code: look through the inventory. Grap the first legal is_thrown 1651 /* New throw code: look through the inventory. Grap the first legal is_thrown
1647 * marked item and throw it to the enemy. 1652 * marked item and throw it to the enemy.
1648 */ 1653 */
1649
1650 for (tmp = op->inv; tmp; tmp = tmp->below) 1654 for (tmp = op->inv; tmp; tmp = tmp->below)
1651 { 1655 {
1652
1653 /* Can't throw invisible objects or items that are applied */ 1656 /* Can't throw invisible objects or items that are applied */
1654 if (tmp->invisible || QUERY_FLAG (tmp, FLAG_APPLIED)) 1657 if (tmp->invisible || QUERY_FLAG (tmp, FLAG_APPLIED))
1655 continue; 1658 continue;
1656 1659
1657 if (QUERY_FLAG (tmp, FLAG_IS_THROWN)) 1660 if (QUERY_FLAG (tmp, FLAG_IS_THROWN))
1780 /* ah, we are within range, detected? take cases */ 1783 /* ah, we are within range, detected? take cases */
1781 if (!enemy->invisible) /* enemy in dark squares... are seen! */ 1784 if (!enemy->invisible) /* enemy in dark squares... are seen! */
1782 return 1; 1785 return 1;
1783 1786
1784 /* hidden or low-quality invisible */ 1787 /* hidden or low-quality invisible */
1785 if (enemy->hide && (rv->distance <= 1) && (RANDOM () % 100 <= hide_discovery)) 1788 if (enemy->hide && (rv->distance <= 1) && (rndm (100) <= hide_discovery))
1786 { 1789 {
1787 make_visible (enemy); 1790 make_visible (enemy);
1788 /* inform players of new status */ 1791 /* inform players of new status */
1789 if (enemy->type == PLAYER && player_can_view (enemy, op)) 1792 if (enemy->type == PLAYER && player_can_view (enemy, op))
1790 new_draw_info_format (NDI_UNIQUE, 0, enemy, "You are discovered by %s!", &op->name); 1793 new_draw_info_format (NDI_UNIQUE, 0, enemy, "You are discovered by %s!", &op->name);
1797 * do something to you. Decreasing the duration of invisible 1800 * do something to you. Decreasing the duration of invisible
1798 * doesn't make a lot of sense IMO, as a bunch of stupid creatures 1801 * doesn't make a lot of sense IMO, as a bunch of stupid creatures
1799 * can then basically negate the spell. The spell isn't negated - 1802 * can then basically negate the spell. The spell isn't negated -
1800 * they just know where you are! 1803 * they just know where you are!
1801 */ 1804 */
1802 if ((RANDOM () % 50) <= hide_discovery) 1805 if ((rndm (50)) <= hide_discovery)
1803 { 1806 {
1804 if (enemy->type == PLAYER) 1807 if (enemy->type == PLAYER)
1805 { 1808 {
1806 new_draw_info_format (NDI_UNIQUE, 0, enemy, "You see %s noticing your position.", query_name (op)); 1809 new_draw_info_format (NDI_UNIQUE, 0, enemy, "You see %s noticing your position.", query_name (op));
1807 } 1810 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines