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.96 by root, Wed Nov 16 23:42:02 2016 UTC vs.
Revision 1.98 by root, Sun Jan 29 02:47:05 2017 UTC

51 npc->enemy = npc->owner->enemy; 51 npc->enemy = npc->owner->enemy;
52 } 52 }
53 53
54 /* periodically, a monster may change its target. Also, if the object 54 /* periodically, a monster may change its target. Also, if the object
55 * has been destroyed, etc, clear the enemy. 55 * has been destroyed, etc, clear the enemy.
56 * TODO: this should be changed, because it invokes to attack forced or 56 * TODO: this should be changed, because it invokes to attack forced or
57 * attacked monsters to leave the attacker alone, before it is destroyed 57 * attacked monsters to leave the attacker alone, before it is destroyed
58 */ 58 */
59 /* I had removed the random target leave, this invokes problems with friendly 59 /* I had removed the random target leave, this invokes problems with friendly
60 * objects, getting attacked and defending herself - they don't try to attack 60 * objects, getting attacked and defending herself - they don't try to attack
61 * again then but perhaps get attack on and on 61 * again then but perhaps get attack on and on
62 * If we include a aggravated flag in , we can handle evil vs evil and good vs good 62 * If we include a aggravated flag in , we can handle evil vs evil and good vs good
63 * too. */ 63 * too. */
64 64
65 if (npc->enemy) 65 if (npc->enemy)
66 { 66 {
105 * of direction, revisit them after looking at all the other spaces. 105 * of direction, revisit them after looking at all the other spaces.
106 * 106 *
107 * Note that being this may skip some number of spaces, it will 107 * Note that being this may skip some number of spaces, it will
108 * not necessarily find the nearest living creature - it basically 108 * not necessarily find the nearest living creature - it basically
109 * chooses one from within a 3 space radius, and since it skips 109 * chooses one from within a 3 space radius, and since it skips
110 * the first few directions, it could very well choose something 110 * the first few directions, it could very well choose something
111 * 3 spaces away even though something directly north is closer. 111 * 3 spaces away even though something directly north is closer.
112 * 112 *
113 * this function is map tile aware. 113 * this function is map tile aware.
114 */ 114 */
115object * 115object *
173 173
174 return tmp; 174 return tmp;
175 } 175 }
176 176
177 /* Here is the main enemy selection. 177 /* Here is the main enemy selection.
178 * We want this: if there is an enemy, attack him until its not possible or 178 * We want this: if there is an enemy, attack him until its not possible or
179 * one of both is dead. 179 * one of both is dead.
180 * If we have no enemy and we are... 180 * If we have no enemy and we are...
181 * a monster: try to find a player, a pet or a friendly monster 181 * a monster: try to find a player, a pet or a friendly monster
182 * a friendly: only target a monster which is targeting you first or targeting a player 182 * a friendly: only target a monster which is targeting you first or targeting a player
183 * a neutral: fight a attacker (but there should be none), then do nothing 183 * a neutral: fight a attacker (but there should be none), then do nothing
250 radius = MIN_MON_RADIUS; 250 radius = MIN_MON_RADIUS;
251 else if (op->map 251 else if (op->map
252 && !enemy->invisible 252 && !enemy->invisible
253 && !stand_in_light (enemy) 253 && !stand_in_light (enemy)
254 && (!op->flag[FLAG_SEE_IN_DARK] || !op->flag [FLAG_SEE_INVISIBLE])) 254 && (!op->flag[FLAG_SEE_IN_DARK] || !op->flag [FLAG_SEE_INVISIBLE]))
255 /* This covers the situation where the monster is in the dark 255 /* This covers the situation where the monster is in the dark
256 * and has an enemy. If the enemy has no carried light (or isnt 256 * and has an enemy. If the enemy has no carried light (or isnt
257 * glowing!) then the monster has trouble finding the enemy. 257 * glowing!) then the monster has trouble finding the enemy.
258 * Remember we already checked to see if the monster can see in 258 * Remember we already checked to see if the monster can see in
259 * the dark. */ 259 * the dark. */
260 min_it (radius, MIN_MON_RADIUS + MAX_DARKNESS - op->map->darklevel ()); 260 min_it (radius, MIN_MON_RADIUS + MAX_DARKNESS - op->map->darklevel ());
261 261
262 if (enemy->flag [FLAG_STEALTH]) 262 if (enemy->flag [FLAG_STEALTH])
263 radius = radius / 2 + 1; 263 radius = radius / 2 + 1;
371 flag = 1; 371 flag = 1;
372 break; 372 break;
373 } 373 }
374 } 374 }
375 375
376 if (((!(monster->pick_up & 32)) && flag) || ((monster->pick_up & 32) && (!flag))) 376 if (((!(monster->pick_up & 32)) && flag) || ((monster->pick_up & 32) && !flag))
377 return 1; 377 return 1;
378 378
379 return 0; 379 return 0;
380} 380}
381 381
395 * affect stacking on this space. 395 * affect stacking on this space.
396 */ 396 */
397static void 397static void
398monster_check_pickup (object *monster) 398monster_check_pickup (object *monster)
399{ 399{
400 object *tmp, *next;
401
402 for (tmp = monster->below; tmp != NULL; tmp = next) 400 for (object *next, *tmp = monster->below; tmp; tmp = next)
403 { 401 {
404 next = tmp->below; 402 next = tmp->below;
403
405 if (monster_can_pick (monster, tmp)) 404 if (monster_can_pick (monster, tmp))
406 { 405 {
407 tmp->remove (); 406 tmp->remove ();
408 tmp = insert_ob_in_ob (tmp, monster); 407 tmp = insert_ob_in_ob (tmp, monster);
409 monster_check_apply (monster, tmp); 408 monster_check_apply (monster, tmp);
536 val = (item->resist[ATNR_PHYSICAL] - other_armour->resist[ATNR_PHYSICAL]) / 5; 535 val = (item->resist[ATNR_PHYSICAL] - other_armour->resist[ATNR_PHYSICAL]) / 5;
537 val += (item->magic - other_armour->magic) * 3; 536 val += (item->magic - other_armour->magic) * 3;
538 537
539 /* for the other protections, do weigh them very much in the equation - 538 /* for the other protections, do weigh them very much in the equation -
540 * it is the armor protection which is most important, because there is 539 * it is the armor protection which is most important, because there is
541 * no good way to know what the player may attack the monster with. 540 * no good way to know what the player may attack the monster with.
542 * So if the new item has better protection than the old, give that higher 541 * So if the new item has better protection than the old, give that higher
543 * value. If the reverse, then decrease the value of this item some. 542 * value. If the reverse, then decrease the value of this item some.
544 */ 543 */
545 for (i = 1; i < NROFATTACKS; i++) 544 for (i = 1; i < NROFATTACKS; i++)
546 { 545 {
652 mon->set_flag (FLAG_READY_SKILL); 651 mon->set_flag (FLAG_READY_SKILL);
653 return; 652 return;
654 } 653 }
655 654
656 /* if we don't match one of the above types, return now. 655 /* if we don't match one of the above types, return now.
657 * can_apply_object will say that we can apply things like flesh, 656 * can_apply_object will say that we can apply things like flesh,
658 * bolts, and whatever else, because it only checks against the 657 * bolts, and whatever else, because it only checks against the
659 * body_info locations. 658 * body_info locations.
660 */ 659 */
661 if (!flag) 660 if (!flag)
662 return; 661 return;
916 object *owner; 915 object *owner;
917 rv_vector rv1; 916 rv_vector rv1;
918 917
919 /* If you want monsters to cast spells over friends, this spell should 918 /* If you want monsters to cast spells over friends, this spell should
920 * be removed. It probably should be in most cases, since monsters still 919 * be removed. It probably should be in most cases, since monsters still
921 * don't care about residual effects (ie, casting a cone which may have a 920 * don't care about residual effects (ie, casting a cone which may have a
922 * clear path to the player, the side aspects of the code will still hit 921 * clear path to the player, the side aspects of the code will still hit
923 * other monsters) 922 * other monsters)
924 */ 923 */
925 if (!(dir = path_to_player (part, pl, 0))) 924 if (!(dir = path_to_player (part, pl, 0)))
926 return 0; 925 return 0;
991 object *owner; 990 object *owner;
992 rv_vector rv1; 991 rv_vector rv1;
993 992
994 /* If you want monsters to cast spells over friends, this spell should 993 /* If you want monsters to cast spells over friends, this spell should
995 * be removed. It probably should be in most cases, since monsters still 994 * be removed. It probably should be in most cases, since monsters still
996 * don't care about residual effects (ie, casting a cone which may have a 995 * don't care about residual effects (ie, casting a cone which may have a
997 * clear path to the player, the side aspects of the code will still hit 996 * clear path to the player, the side aspects of the code will still hit
998 * other monsters) 997 * other monsters)
999 */ 998 */
1000 if (!(dir = path_to_player (part, pl, 0))) 999 if (!(dir = path_to_player (part, pl, 0)))
1001 return 0; 1000 return 0;
1033 1032
1034/* monster_use_skill()-implemented 95-04-28 to allow monster skill use. 1033/* monster_use_skill()-implemented 95-04-28 to allow monster skill use.
1035 * Note that monsters do not need the skills SK_MELEE_WEAPON and 1034 * Note that monsters do not need the skills SK_MELEE_WEAPON and
1036 * SK_MISSILE_WEAPON to make those respective attacks, if we 1035 * SK_MISSILE_WEAPON to make those respective attacks, if we
1037 * required that we would drastically increase the memory 1036 * required that we would drastically increase the memory
1038 * requirements of CF!! 1037 * requirements of CF!!
1039 * 1038 *
1040 * The skills we are treating here are all but those. -b.t. 1039 * The skills we are treating here are all but those. -b.t.
1041 * 1040 *
1042 * At the moment this is only useful for throwing, perhaps for 1041 * 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 1042 * stealing. TODO: This should be more integrated in the game. -MT, 25.11.01
1044 */ 1043 */
1045static int 1044static int
1284 if (op->stats.Con > 0 && op->stats.hp < op->stats.maxhp) 1283 if (op->stats.Con > 0 && op->stats.hp < op->stats.maxhp)
1285 { 1284 {
1286 /* last heal is in funny units. Dividing by speed puts 1285 /* last heal is in funny units. Dividing by speed puts
1287 * the regeneration rate on a basis of time instead of 1286 * the regeneration rate on a basis of time instead of
1288 * #moves the monster makes. The scaling by 8 is 1287 * #moves the monster makes. The scaling by 8 is
1289 * to capture 8th's of a hp fraction regens 1288 * to capture 8th's of a hp fraction regens
1290 */ 1289 */
1291 uint32_t last_heal = op->last_heal + op->stats.Con * 8 / op->speed; 1290 uint32_t last_heal = op->last_heal + op->stats.Con * 8 / op->speed;
1292 op->stats.hp = min (op->stats.hp + last_heal / 32, op->stats.maxhp); /* causes Con/4 hp/tick */ 1291 op->stats.hp = min (op->stats.hp + last_heal / 32, op->stats.maxhp); /* causes Con/4 hp/tick */
1293 op->last_heal = last_heal % 32; 1292 op->last_heal = last_heal % 32;
1294 1293
1301 if (op->stats.Pow > 0 && op->stats.sp < op->stats.maxsp) 1300 if (op->stats.Pow > 0 && op->stats.sp < op->stats.maxsp)
1302 { 1301 {
1303 /* last_sp is in funny units. Dividing by speed puts 1302 /* last_sp is in funny units. Dividing by speed puts
1304 * the regeneration rate on a basis of time instead of 1303 * the regeneration rate on a basis of time instead of
1305 * #moves the monster makes. The scaling by 8 is 1304 * #moves the monster makes. The scaling by 8 is
1306 * to capture 8th's of a sp fraction regens 1305 * to capture 8th's of a sp fraction regens
1307 */ 1306 */
1308 1307
1309 uint32_t last_sp = op->last_sp + op->stats.Pow * 8 / op->speed; 1308 uint32_t last_sp = op->last_sp + op->stats.Pow * 8 / op->speed;
1310 op->stats.sp = min (op->stats.sp + last_sp / 128, op->stats.maxsp); /* causes Pow/16 sp/tick */ 1309 op->stats.sp = min (op->stats.sp + last_sp / 128, op->stats.maxsp); /* causes Pow/16 sp/tick */
1311 op->last_sp = last_sp % 128; 1310 op->last_sp = last_sp % 128;
1436 { 1435 {
1437 get_rangevector (part, enemy, &rv1, 0x1); 1436 get_rangevector (part, enemy, &rv1, 0x1);
1438 dir = rv1.direction; 1437 dir = rv1.direction;
1439 1438
1440 /* hm, not sure about this part - in original was a scared flag here too 1439 /* hm, not sure about this part - in original was a scared flag here too
1441 * but that we test above... so can be old code here 1440 * but that we test above... so can be old code here
1442 */ 1441 */
1443 if (op->flag [FLAG_RUN_AWAY]) 1442 if (op->flag [FLAG_RUN_AWAY])
1444 dir = absdir (dir + 4); 1443 dir = absdir (dir + 4);
1445 1444
1446 if (op->flag [FLAG_CONFUSED]) 1445 if (op->flag [FLAG_CONFUSED])
1657 1656
1658 return 0; 1657 return 0;
1659} 1658}
1660 1659
1661/* determine if we can 'detect' the enemy. Check for walls blocking the 1660/* determine if we can 'detect' the enemy. Check for walls blocking the
1662 * los. Also, just because its hidden/invisible, we may be sensitive/smart 1661 * los. Also, just because its hidden/invisible, we may be sensitive/smart
1663 * enough (based on Wis & Int) to figure out where the enemy is. -b.t. 1662 * enough (based on Wis & Int) to figure out where the enemy is. -b.t.
1664 * modified by MSW to use the get_rangevector so that map tiling works 1663 * modified by MSW to use the get_rangevector so that map tiling works
1665 * properly. I also so odd code in place that checked for x distance 1664 * properly. I also so odd code in place that checked for x distance
1666 * OR y distance being within some range - that seemed wrong - both should 1665 * OR y distance being within some range - that seemed wrong - both should
1667 * be within the valid range. MSW 2001-08-05 1666 * be within the valid range. MSW 2001-08-05
1668 * Returns 0 if enemy can not be detected, 1 if it is detected 1667 * Returns 0 if enemy can not be detected, 1 if it is detected
1693 */ 1692 */
1694 if (op->is_player ()) 1693 if (op->is_player ())
1695 return 0; 1694 return 0;
1696 1695
1697 /* Quality invisible? Bah, we wont see them w/o SEE_INVISIBLE 1696 /* Quality invisible? Bah, we wont see them w/o SEE_INVISIBLE
1698 * flag (which was already checked) in can_see_enemy (). Lets get out of here 1697 * flag (which was already checked) in can_see_enemy (). Lets get out of here
1699 */ 1698 */
1700 if (enemy->invisible && (!enemy->contr || (!enemy->contr->tmp_invis && !enemy->contr->hidden))) 1699 if (enemy->invisible && (!enemy->contr || (!enemy->contr->tmp_invis && !enemy->contr->hidden)))
1701 return 0; 1700 return 0;
1702 1701
1703 int radius = MIN_MON_RADIUS; 1702 int radius = MIN_MON_RADIUS;
1728 1727
1729 radius += bonus / 5; 1728 radius += bonus / 5;
1730 hide_discovery += bonus * 5; 1729 hide_discovery += bonus * 5;
1731 } /* else creature has modifiers for hiding */ 1730 } /* else creature has modifiers for hiding */
1732 1731
1733 /* Radii stealth adjustment. Only if you are stealthy 1732 /* Radii stealth adjustment. Only if you are stealthy
1734 * will you be able to sneak up closer to creatures */ 1733 * will you be able to sneak up closer to creatures */
1735 if (enemy->flag [FLAG_STEALTH]) 1734 if (enemy->flag [FLAG_STEALTH])
1736 { 1735 {
1737 radius /= 2; 1736 radius /= 2;
1738 hide_discovery /= 3; 1737 hide_discovery /= 3;
1747 if (op->flag [FLAG_SEE_IN_DARK] && !is_true_undead (enemy)) 1746 if (op->flag [FLAG_SEE_IN_DARK] && !is_true_undead (enemy))
1748 radius += op->map->darklevel () / 2; 1747 radius += op->map->darklevel () / 2;
1749 else 1748 else
1750 radius -= op->map->darklevel () / 2; 1749 radius -= op->map->darklevel () / 2;
1751 1750
1752 /* op next to a monster (and not in complete darkness) 1751 /* op next to a monster (and not in complete darkness)
1753 * the monster should have a chance to see you. 1752 * the monster should have a chance to see you.
1754 */ 1753 */
1755 if (radius < MIN_MON_RADIUS && op->map->darklevel () < MAX_DARKNESS && rv->distance <= 1) 1754 if (radius < MIN_MON_RADIUS && op->map->darklevel () < MAX_DARKNESS && rv->distance <= 1)
1756 radius = MIN_MON_RADIUS; 1755 radius = MIN_MON_RADIUS;
1757 } /* if on dark map */ 1756 } /* if on dark map */
1758 1757
1808 /* Wasn't detected above, so still hidden */ 1807 /* Wasn't detected above, so still hidden */
1809 return 0; 1808 return 0;
1810} 1809}
1811 1810
1812/* determine if op stands in a lighted square. This is not a very 1811/* determine if op stands in a lighted square. This is not a very
1813 * intelligent algorithm. For one thing, we ignore los here, SO it 1812 * intelligent algorithm. For one thing, we ignore los here, SO it
1814 * is possible for a bright light to illuminate a player on the 1813 * is possible for a bright light to illuminate a player on the
1815 * other side of a wall (!). 1814 * other side of a wall (!).
1816 */ 1815 */
1817int 1816int
1818stand_in_light (object *op) 1817stand_in_light (object *op)
1819{ 1818{
1820 if (op) 1819 if (op)
1846 } 1845 }
1847 1846
1848 return 0; 1847 return 0;
1849} 1848}
1850 1849
1851/* assuming no walls/barriers, lets check to see if its *possible* 1850/* assuming no walls/barriers, lets check to see if its *possible*
1852 * to see an enemy. Note, "detection" is different from "seeing". 1851 * to see an enemy. Note, "detection" is different from "seeing".
1853 * See can_detect_enemy() for more details. -b.t. 1852 * See can_detect_enemy() for more details. -b.t.
1854 * return 0 if can't be seen, 1 if can be 1853 * return 0 if can't be seen, 1 if can be
1855 */ 1854 */
1856int 1855int
1861 /* safety */ 1860 /* safety */
1862 if (!looker || !enemy || !looker->flag [FLAG_ALIVE]) 1861 if (!looker || !enemy || !looker->flag [FLAG_ALIVE])
1863 return 0; 1862 return 0;
1864 1863
1865 /* we dont give a full treatment of xrays here (shorter range than normal, 1864 /* we dont give a full treatment of xrays here (shorter range than normal,
1866 * see through walls). Should we change the code elsewhere to make you 1865 * see through walls). Should we change the code elsewhere to make you
1867 * blind even if you can xray? 1866 * blind even if you can xray?
1868 */ 1867 */
1869 if (looker->flag [FLAG_BLIND] && !looker->flag [FLAG_XRAYS]) 1868 if (looker->flag [FLAG_BLIND] && !looker->flag [FLAG_XRAYS])
1870 return 0; 1869 return 0;
1871 1870
1872 /* checking for invisible things */ 1871 /* checking for invisible things */
1873 if (enemy->invisible) 1872 if (enemy->invisible)
1874 { 1873 {
1875 /* HIDDEN ENEMY. by definition, you can't see hidden stuff! 1874 /* HIDDEN ENEMY. by definition, you can't see hidden stuff!
1876 * However,if you carry any source of light, then the hidden 1875 * However,if you carry any source of light, then the hidden
1877 * creature is seeable (and stupid) */ 1876 * creature is seeable (and stupid) */
1878 1877
1879 if (enemy->has_carried_lights ()) 1878 if (enemy->has_carried_lights ())
1880 { 1879 {
1899 } 1898 }
1900 else if (looker->is_player ()) /* for players, a (possible) shortcut */ 1899 else if (looker->is_player ()) /* for players, a (possible) shortcut */
1901 if (player_can_view (looker, enemy)) 1900 if (player_can_view (looker, enemy))
1902 return 1; 1901 return 1;
1903 1902
1904 /* ENEMY IN DARK MAP. Without infravision, the enemy is not seen 1903 /* ENEMY IN DARK MAP. Without infravision, the enemy is not seen
1905 * unless they carry a light or stand in light. Darkness doesnt 1904 * unless they carry a light or stand in light. Darkness doesnt
1906 * inhibit the undead per se (but we should give their archs 1905 * inhibit the undead per se (but we should give their archs
1907 * CAN_SEE_IN_DARK, this is just a safety 1906 * CAN_SEE_IN_DARK, this is just a safety
1908 * we care about the enemy maps status, not the looker. 1907 * we care about the enemy maps status, not the looker.
1909 * only relevant for tiled maps, but it is possible that the 1908 * only relevant for tiled maps, but it is possible that the
1910 * enemy is on a bright map and the looker on a dark - in that 1909 * enemy is on a bright map and the looker on a dark - in that
1911 * case, the looker can still see the enemy 1910 * case, the looker can still see the enemy
1912 */ 1911 */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines