… | |
… | |
35 | * set to sane values. |
35 | * set to sane values. |
36 | */ |
36 | */ |
37 | object * |
37 | object * |
38 | check_enemy (object *npc, rv_vector * rv) |
38 | check_enemy (object *npc, rv_vector * rv) |
39 | { |
39 | { |
40 | |
|
|
41 | /* if this is pet, let him attack the same enemy as his owner |
40 | /* if this is pet, let him attack the same enemy as his owner |
42 | * TODO: when there is no ower enemy, try to find a target, |
41 | * TODO: when there is no ower enemy, try to find a target, |
43 | * which CAN attack the owner. */ |
42 | * which CAN attack the owner. */ |
44 | if ((npc->attack_movement & HI4) == PETMOVE) |
43 | if ((npc->attack_movement & HI4) == PETMOVE) |
45 | { |
44 | { |
… | |
… | |
324 | op->last_heal += (int) ((float) (8 * op->stats.Con) / FABS (op->speed)); |
323 | op->last_heal += (int) ((float) (8 * op->stats.Con) / FABS (op->speed)); |
325 | op->stats.hp = MIN ((sint32) op->stats.hp + op->last_heal / 32, op->stats.maxhp); /* causes Con/4 hp/tick */ |
324 | op->stats.hp = MIN ((sint32) op->stats.hp + op->last_heal / 32, op->stats.maxhp); /* causes Con/4 hp/tick */ |
326 | op->last_heal %= 32; |
325 | op->last_heal %= 32; |
327 | |
326 | |
328 | /* So if the monster has gained enough HP that they are no longer afraid */ |
327 | /* So if the monster has gained enough HP that they are no longer afraid */ |
329 | if (QUERY_FLAG (op, FLAG_RUN_AWAY) && op->stats.hp >= (signed short) (((float) op->run_away / (float) 100) * (float) op->stats.maxhp)) |
328 | if (QUERY_FLAG (op, FLAG_RUN_AWAY) && op->stats.hp >= (signed short)(((float)op->run_away / 100.f) * (float)op->stats.maxhp)) |
330 | CLEAR_FLAG (op, FLAG_RUN_AWAY); |
329 | CLEAR_FLAG (op, FLAG_RUN_AWAY); |
331 | |
330 | |
332 | if (op->stats.hp > op->stats.maxhp) |
331 | if (op->stats.hp > op->stats.maxhp) |
333 | op->stats.hp = op->stats.maxhp; |
332 | op->stats.hp = op->stats.maxhp; |
334 | } |
333 | } |
335 | |
334 | |
336 | /* generate sp, if applicable */ |
335 | /* generate sp, if applicable */ |
337 | if (op->stats.Pow > 0 && op->stats.sp < op->stats.maxsp) |
336 | if (op->stats.Pow > 0 && op->stats.sp < op->stats.maxsp) |
338 | { |
337 | { |
339 | /* last_sp is in funny units. Dividing by speed puts |
338 | /* last_sp is in funny units. Dividing by speed puts |
340 | * the regeneration rate on a basis of time instead of |
339 | * the regeneration rate on a basis of time instead of |
341 | * #moves the monster makes. The scaling by 8 is |
340 | * #moves the monster makes. The scaling by 8 is |
342 | * to capture 8th's of a sp fraction regens |
341 | * to capture 8th's of a sp fraction regens |
343 | * |
342 | * |
344 | * Cast to sint32 before comparing to maxhp since otherwise an (sint16) |
343 | * Cast to sint32 before comparing to maxhp since otherwise an (sint16) |
345 | * overflow might produce monsters with negative sp. |
344 | * overflow might produce monsters with negative sp. |
346 | */ |
345 | */ |
347 | |
346 | |
348 | op->last_sp += (int) ((float) (8 * op->stats.Pow) / FABS (op->speed)); |
347 | op->last_sp += (int) ((float) (8 * op->stats.Pow) / fabsf (op->speed)); |
349 | op->stats.sp = MIN (op->stats.sp + op->last_sp / 128, op->stats.maxsp); /* causes Pow/16 sp/tick */ |
348 | op->stats.sp = min (op->stats.sp + op->last_sp / 128, op->stats.maxsp); /* causes Pow/16 sp/tick */ |
350 | op->last_sp %= 128; |
349 | op->last_sp %= 128; |
351 | } |
350 | } |
352 | |
351 | |
353 | /* this should probably get modified by many more values. |
352 | /* this should probably get modified by many more values. |
354 | * (eg, creatures resistance to fear, level, etc. ) |
353 | * (eg, creatures resistance to fear, level, etc. ) |
… | |
… | |
505 | if (monster_use_bow (op, part, enemy, dir)) |
504 | if (monster_use_bow (op, part, enemy, dir)) |
506 | return 0; |
505 | return 0; |
507 | } /* for processing of all parts */ |
506 | } /* for processing of all parts */ |
508 | } /* If not scared */ |
507 | } /* If not scared */ |
509 | |
508 | |
510 | |
|
|
511 | part = rv.part; |
509 | part = rv.part; |
512 | dir = rv.direction; |
510 | dir = rv.direction; |
|
|
511 | |
|
|
512 | #if DEVEL |
|
|
513 | // if the enemy is a player, we have los. if los says we |
|
|
514 | // can directly reach the player, we do not deviate. |
|
|
515 | // for non-players, we never deviate |
|
|
516 | if (enemy->contr && enemy->contr->darkness_at (op->map, op->x, op->y) == LOS_BLOCKED) |
|
|
517 | { |
|
|
518 | int sdir = 0; |
|
|
519 | |
|
|
520 | for (int dir = 1; dir <= 8; ++dir) |
|
|
521 | { |
|
|
522 | mapxy pos (op); pos.move (dir); |
|
|
523 | if (pos.normalise ()) |
|
|
524 | { |
|
|
525 | mapspace &ms = pos.ms (); |
|
|
526 | |
|
|
527 | if (ms.smell > op->ms ().smell) |
|
|
528 | { |
|
|
529 | printf ("%s: found smell, following it, apparently (%d, %d)\n",& op->name,op->ms().smell,ms.smell);//D |
|
|
530 | op->ms ().smell = ms.smell - 1; |
|
|
531 | sdir = dir; |
|
|
532 | |
|
|
533 | // perturbing the path might let the monster lose track, |
|
|
534 | // but it will also wide the actual path, spreading information |
|
|
535 | if (!rndm (20)) |
|
|
536 | sdir += absdir (1 - rndm (2) * 2); |
|
|
537 | } |
|
|
538 | } |
|
|
539 | } |
|
|
540 | |
|
|
541 | if (sdir) |
|
|
542 | dir = sdir; |
|
|
543 | else |
|
|
544 | // no better smell found, so assume the player jumped, and erase this smell |
|
|
545 | {if (op->ms ().smell) printf ("erasing smell %d\n", op->ms ().smell);//D |
|
|
546 | ordered_mapwalk_begin (op, -1, -1, 1, 1) |
|
|
547 | if (m) |
|
|
548 | m->at (nx, ny).smell = 0; |
|
|
549 | ordered_mapwalk_end |
|
|
550 | }//D |
|
|
551 | } |
|
|
552 | |
|
|
553 | #endif |
513 | |
554 | |
514 | if (QUERY_FLAG (op, FLAG_SCARED) || QUERY_FLAG (op, FLAG_RUN_AWAY)) |
555 | if (QUERY_FLAG (op, FLAG_SCARED) || QUERY_FLAG (op, FLAG_RUN_AWAY)) |
515 | dir = absdir (dir + 4); |
556 | dir = absdir (dir + 4); |
516 | |
557 | |
517 | if (QUERY_FLAG (op, FLAG_CONFUSED)) |
558 | if (QUERY_FLAG (op, FLAG_CONFUSED)) |
… | |
… | |
571 | } |
612 | } |
572 | |
613 | |
573 | if (QUERY_FLAG (op, FLAG_SCARED) || !can_hit (part, enemy, &rv) || QUERY_FLAG (op, FLAG_RUN_AWAY)) |
614 | if (QUERY_FLAG (op, FLAG_SCARED) || !can_hit (part, enemy, &rv) || QUERY_FLAG (op, FLAG_RUN_AWAY)) |
574 | { |
615 | { |
575 | /* Try move around corners if !close */ |
616 | /* Try move around corners if !close */ |
576 | int maxdiff = (QUERY_FLAG (op, FLAG_ONLY_ATTACK) || RANDOM () & 1) ? 1 : 2; |
617 | int maxdiff = (QUERY_FLAG (op, FLAG_ONLY_ATTACK) || rndm (2)) ? 1 : 2; |
577 | |
618 | |
578 | for (diff = 1; diff <= maxdiff; diff++) |
619 | for (diff = 1; diff <= maxdiff; diff++) |
579 | { |
620 | { |
580 | /* try different detours */ |
621 | /* try different detours */ |
581 | int m = 1 - (RANDOM () & 2); /* Try left or right first? */ |
622 | int m = 1 - rndm (2) * 2; /* Try left or right first? */ |
582 | |
623 | |
583 | if (move_object (op, absdir (dir + diff * m)) || move_object (op, absdir (dir - diff * m))) |
624 | if (move_object (op, absdir (dir + diff * m)) || move_object (op, absdir (dir - diff * m))) |
584 | return 0; |
625 | return 0; |
585 | } |
626 | } |
586 | } |
627 | } |
… | |
… | |
1689 | radius = max (MIN_MON_RADIUS, op->stats.Wis / 5 + 1); |
1730 | radius = max (MIN_MON_RADIUS, op->stats.Wis / 5 + 1); |
1690 | else |
1731 | else |
1691 | { /* a level/INT/Dex adjustment for hiding */ |
1732 | { /* a level/INT/Dex adjustment for hiding */ |
1692 | int bonus = op->level / 2 + op->stats.Int / 5; |
1733 | int bonus = op->level / 2 + op->stats.Int / 5; |
1693 | |
1734 | |
1694 | if (enemy->type == PLAYER) |
1735 | if (enemy->is_player ()) |
1695 | { |
1736 | { |
1696 | if (object *sk_hide = find_skill_by_number (enemy, SK_HIDING)) |
1737 | if (object *sk_hide = find_skill_by_number (enemy, SK_HIDING)) |
1697 | bonus -= sk_hide->level; |
1738 | bonus -= sk_hide->level; |
1698 | else |
1739 | else |
1699 | { |
1740 | { |
… | |
… | |
1864 | */ |
1905 | */ |
1865 | if (!QUERY_FLAG (looker, FLAG_SEE_INVISIBLE)) |
1906 | if (!QUERY_FLAG (looker, FLAG_SEE_INVISIBLE)) |
1866 | if (makes_invisible_to (enemy, looker)) |
1907 | if (makes_invisible_to (enemy, looker)) |
1867 | return 0; |
1908 | return 0; |
1868 | } |
1909 | } |
1869 | else if (looker->type == PLAYER) /* for players, a (possible) shortcut */ |
1910 | else if (looker->is_player ()) /* for players, a (possible) shortcut */ |
1870 | if (player_can_view (looker, enemy)) |
1911 | if (player_can_view (looker, enemy)) |
1871 | return 1; |
1912 | return 1; |
1872 | |
1913 | |
1873 | /* ENEMY IN DARK MAP. Without infravision, the enemy is not seen |
1914 | /* ENEMY IN DARK MAP. Without infravision, the enemy is not seen |
1874 | * unless they carry a light or stand in light. Darkness doesnt |
1915 | * unless they carry a light or stand in light. Darkness doesnt |