… | |
… | |
210 | ob->close_container (); //TODO: client-specific |
210 | ob->close_container (); //TODO: client-specific |
211 | |
211 | |
212 | ns->update_look = 0; |
212 | ns->update_look = 0; |
213 | ns->look_position = 0; |
213 | ns->look_position = 0; |
214 | |
214 | |
215 | clear_los (this); |
215 | clear_los (); |
216 | |
216 | |
217 | ns->reset_stats (); |
217 | ns->reset_stats (); |
218 | |
218 | |
219 | /* make sure he's a player -- needed because of class change. */ |
219 | /* make sure he's a player -- needed because of class change. */ |
220 | ob->type = PLAYER; // we are paranoid |
220 | ob->type = PLAYER; // we are paranoid |
… | |
… | |
366 | attachable::do_destroy (); |
366 | attachable::do_destroy (); |
367 | |
367 | |
368 | if (ob) |
368 | if (ob) |
369 | { |
369 | { |
370 | ob->destroy_inv (false); |
370 | ob->destroy_inv (false); |
371 | ob->destroy (true); |
371 | ob->destroy (); |
372 | } |
372 | } |
373 | |
373 | |
374 | ob = observe = 0; |
374 | ob = observe = 0; |
375 | } |
375 | } |
376 | |
376 | |
… | |
… | |
668 | || op->type == CLOAK || op->type == HELMET |
668 | || op->type == CLOAK || op->type == HELMET |
669 | || op->type == SHIELD || op->type == GLOVES |
669 | || op->type == SHIELD || op->type == GLOVES |
670 | || op->type == BRACERS || op->type == GIRDLE)) |
670 | || op->type == BRACERS || op->type == GIRDLE)) |
671 | || (!QUERY_FLAG (pl, FLAG_USE_WEAPON) && op->type == WEAPON)) |
671 | || (!QUERY_FLAG (pl, FLAG_USE_WEAPON) && op->type == WEAPON)) |
672 | { |
672 | { |
673 | op->destroy (true); |
673 | op->destroy (); |
674 | continue; |
674 | continue; |
675 | } |
675 | } |
676 | } |
676 | } |
677 | |
677 | |
678 | /* This really needs to be better - we should really give |
678 | /* This really needs to be better - we should really give |
… | |
… | |
689 | if (tmp->type == op->type && tmp->name == op->name) |
689 | if (tmp->type == op->type && tmp->name == op->name) |
690 | break; |
690 | break; |
691 | |
691 | |
692 | if (tmp) |
692 | if (tmp) |
693 | { |
693 | { |
694 | op->destroy (true); |
694 | op->destroy (); |
695 | LOG (llevError, "give_initial_items: Removing duplicate object %s\n", &tmp->name); |
695 | LOG (llevError, "give_initial_items: Removing duplicate object %s\n", &tmp->name); |
696 | continue; |
696 | continue; |
697 | } |
697 | } |
698 | |
698 | |
699 | if (op->nrof > 1) |
699 | if (op->nrof > 1) |
… | |
… | |
714 | CLEAR_FLAG (op, FLAG_DAMNED); |
714 | CLEAR_FLAG (op, FLAG_DAMNED); |
715 | } |
715 | } |
716 | |
716 | |
717 | if (op->type == SPELL) |
717 | if (op->type == SPELL) |
718 | { |
718 | { |
719 | op->destroy (true); |
719 | op->destroy (); |
720 | continue; |
720 | continue; |
721 | } |
721 | } |
722 | else if (op->type == SKILL) |
722 | else if (op->type == SKILL) |
723 | { |
723 | { |
724 | SET_FLAG (op, FLAG_CAN_USE_SKILL); |
724 | SET_FLAG (op, FLAG_CAN_USE_SKILL); |
… | |
… | |
931 | LOG (llevDebug, "Fleeing player is dead.\n"); |
931 | LOG (llevDebug, "Fleeing player is dead.\n"); |
932 | CLEAR_FLAG (op, FLAG_SCARED); |
932 | CLEAR_FLAG (op, FLAG_SCARED); |
933 | return; |
933 | return; |
934 | } |
934 | } |
935 | |
935 | |
936 | if (op->enemy == NULL) |
936 | if (!op->enemy) |
937 | { |
937 | { |
938 | LOG (llevDebug, "Fleeing player had no enemy.\n"); |
938 | LOG (llevDebug, "Fleeing player had no enemy.\n"); |
939 | CLEAR_FLAG (op, FLAG_SCARED); |
939 | CLEAR_FLAG (op, FLAG_SCARED); |
940 | return; |
940 | return; |
941 | } |
941 | } |
942 | |
942 | |
943 | /* Seen some crashes here. Since we don't store an |
|
|
944 | * op->enemy_count, it is possible that something destroys the |
|
|
945 | * actual enemy, and the object is recycled. |
|
|
946 | */ |
|
|
947 | if (op->enemy->map == NULL) |
|
|
948 | { |
|
|
949 | CLEAR_FLAG (op, FLAG_SCARED); |
|
|
950 | op->enemy = NULL; |
|
|
951 | return; |
|
|
952 | } |
|
|
953 | |
|
|
954 | if (!(random_roll (0, 4, op, PREFER_LOW)) && did_make_save (op, op->level, 0)) |
943 | if (!(random_roll (0, 4, op, PREFER_LOW)) && did_make_save (op, op->level, 0)) |
955 | { |
944 | { |
956 | op->enemy = NULL; |
945 | op->enemy = NULL; |
957 | CLEAR_FLAG (op, FLAG_SCARED); |
946 | CLEAR_FLAG (op, FLAG_SCARED); |
958 | return; |
947 | return; |
… | |
… | |
961 | get_rangevector (op, op->enemy, &rv, 0); |
950 | get_rangevector (op, op->enemy, &rv, 0); |
962 | |
951 | |
963 | dir = absdir (4 + rv.direction); |
952 | dir = absdir (4 + rv.direction); |
964 | for (diff = 0; diff < 3; diff++) |
953 | for (diff = 0; diff < 3; diff++) |
965 | { |
954 | { |
966 | int m = 1 - (RANDOM () & 2); |
955 | int m = 1 - rndm (2) * 2; |
967 | |
956 | |
968 | if (move_ob (op, absdir (dir + diff * m), op) || (diff == 0 && move_ob (op, absdir (dir - diff * m), op))) |
957 | if (move_ob (op, absdir (dir + diff * m), op) || (diff == 0 && move_ob (op, absdir (dir - diff * m), op))) |
969 | return; |
958 | return; |
970 | } |
959 | } |
971 | |
960 | |
… | |
… | |
1016 | |
1005 | |
1017 | if (op->contr->search_str[0] != '\0' && settings.search_items == TRUE) |
1006 | if (op->contr->search_str[0] != '\0' && settings.search_items == TRUE) |
1018 | { |
1007 | { |
1019 | if (item_matched_string (op, tmp, op->contr->search_str)) |
1008 | if (item_matched_string (op, tmp, op->contr->search_str)) |
1020 | CHK_PICK_PICKUP; |
1009 | CHK_PICK_PICKUP; |
|
|
1010 | |
1021 | continue; |
1011 | continue; |
1022 | } |
1012 | } |
1023 | |
1013 | |
1024 | /* high not bit set? We're using the old autopickup model */ |
1014 | /* high not bit set? We're using the old autopickup model */ |
1025 | if (!(op->contr->mode & PU_NEWMODE)) |
1015 | if (!(op->contr->mode & PU_NEWMODE)) |
… | |
… | |
1462 | for (i = 0, found = 0; i < 20; i++) |
1452 | for (i = 0, found = 0; i < 20; i++) |
1463 | { |
1453 | { |
1464 | x += freearr_x[dir]; |
1454 | x += freearr_x[dir]; |
1465 | y += freearr_y[dir]; |
1455 | y += freearr_y[dir]; |
1466 | mflags = get_map_flags (m, &m, x, y, &x, &y); |
1456 | mflags = get_map_flags (m, &m, x, y, &x, &y); |
|
|
1457 | |
1467 | if (mflags & P_OUT_OF_MAP || mflags & P_BLOCKSVIEW) |
1458 | if (mflags & P_OUT_OF_MAP || mflags & P_BLOCKSVIEW) |
1468 | { |
1459 | { |
1469 | tmp = NULL; |
1460 | tmp = 0; |
1470 | break; |
1461 | break; |
1471 | } |
1462 | } |
1472 | else if (GET_MAP_MOVE_BLOCK (m, x, y) == MOVE_FLY_LOW) |
1463 | else if (GET_MAP_MOVE_BLOCK (m, x, y) == MOVE_FLY_LOW) |
1473 | { |
1464 | { |
1474 | /* This block presumes arrows and the like are MOVE_FLY_SLOW - |
1465 | /* This block presumes arrows and the like are MOVE_FLY_SLOW - |
1475 | * perhaps a bad assumption. |
1466 | * perhaps a bad assumption. |
1476 | */ |
1467 | */ |
1477 | tmp = NULL; |
1468 | tmp = 0; |
1478 | break; |
1469 | break; |
1479 | } |
1470 | } |
|
|
1471 | |
1480 | if (mflags & P_IS_ALIVE) |
1472 | if (mflags & P_IS_ALIVE) |
1481 | { |
|
|
1482 | for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above) |
1473 | for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above) |
1483 | if (QUERY_FLAG (tmp, FLAG_ALIVE)) |
1474 | if (QUERY_FLAG (tmp, FLAG_ALIVE)) |
1484 | { |
|
|
1485 | found++; |
|
|
1486 | break; |
|
|
1487 | } |
|
|
1488 | if (found) |
|
|
1489 | break; |
1475 | break; |
1490 | } |
|
|
1491 | } |
1476 | } |
1492 | if (tmp == NULL) |
1477 | |
|
|
1478 | if (!tmp) |
1493 | return find_arrow (op, type); |
1479 | return find_arrow (op, type); |
1494 | |
1480 | |
1495 | if (tmp->head) |
1481 | if (tmp->head) |
1496 | tmp = tmp->head; |
1482 | tmp = tmp->head; |
1497 | |
1483 | |
… | |
… | |
1542 | if (bow->below) |
1528 | if (bow->below) |
1543 | { |
1529 | { |
1544 | bow->remove (); |
1530 | bow->remove (); |
1545 | op->insert (bow); |
1531 | op->insert (bow); |
1546 | } |
1532 | } |
1547 | |
|
|
1548 | } |
1533 | } |
1549 | |
1534 | |
1550 | if (!bow->race || !bow->skill) |
1535 | if (!bow->race || !bow->skill) |
1551 | { |
1536 | { |
1552 | new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is broken.", &bow->name); |
1537 | new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s is broken.", &bow->name); |
… | |
… | |
1579 | |
1564 | |
1580 | /* this should not happen, but sometimes does */ |
1565 | /* this should not happen, but sometimes does */ |
1581 | if (arrow->nrof == 0) |
1566 | if (arrow->nrof == 0) |
1582 | { |
1567 | { |
1583 | LOG (llevError | logBacktrace, "arrow (%s) has nrof 0\n", arrow->debug_desc ()); |
1568 | LOG (llevError | logBacktrace, "arrow (%s) has nrof 0\n", arrow->debug_desc ()); |
1584 | arrow->destroy (true); |
1569 | arrow->destroy (); |
1585 | return 0; |
1570 | return 0; |
1586 | } |
1571 | } |
1587 | |
1572 | |
1588 | left = arrow; /* these are arrows left to the player */ |
1573 | left = arrow; /* these are arrows left to the player */ |
1589 | arrow = arrow->split (); |
1574 | arrow = arrow->split (); |
… | |
… | |
1675 | * hence the function name. |
1660 | * hence the function name. |
1676 | */ |
1661 | */ |
1677 | int |
1662 | int |
1678 | player_fire_bow (object *op, int dir) |
1663 | player_fire_bow (object *op, int dir) |
1679 | { |
1664 | { |
1680 | int ret = 0, wcmod = 0; |
1665 | int ret; |
1681 | |
1666 | |
1682 | if (op->contr->bowtype == bow_bestarrow) |
1667 | if (op->contr->bowtype == bow_bestarrow) |
1683 | { |
1668 | { |
1684 | ret = fire_bow (op, op, pick_arrow_target (op, op->contr->ranged_ob->race, dir), dir, 0, op->x, op->y); |
1669 | ret = fire_bow (op, op, pick_arrow_target (op, op->contr->ranged_ob->race, dir), dir, 0, op->x, op->y); |
1685 | } |
1670 | } |
1686 | else if (op->contr->bowtype >= bow_n && op->contr->bowtype <= bow_nw) |
1671 | else if (op->contr->bowtype >= bow_n && op->contr->bowtype <= bow_nw) |
1687 | { |
1672 | { |
1688 | if (!similar_direction (dir, op->contr->bowtype - bow_n + 1)) |
1673 | int wcmod = similar_direction (dir, op->contr->bowtype - bow_n + 1) ? 0 : -1; |
1689 | wcmod = -1; |
|
|
1690 | |
|
|
1691 | ret = fire_bow (op, op, NULL, op->contr->bowtype - bow_n + 1, wcmod, op->x, op->y); |
1674 | ret = fire_bow (op, op, NULL, op->contr->bowtype - bow_n + 1, wcmod, op->x, op->y); |
1692 | } |
1675 | } |
1693 | else if (op->contr->bowtype == bow_threewide) |
1676 | else if (op->contr->bowtype == bow_threewide) |
1694 | { |
1677 | { |
1695 | ret = fire_bow (op, op, NULL, dir, 0, op->x, op->y); |
1678 | ret = fire_bow (op, op, NULL, dir, 0, op->x, op->y); |
1696 | ret |= fire_bow (op, op, NULL, dir, -5, op->x + freearr_x[absdir (dir + 2)], op->y + freearr_y[absdir (dir + 2)]); |
1679 | ret |= fire_bow (op, op, NULL, dir, -5, op->x + freearr_x[absdir (dir + 2)], op->y + freearr_y[absdir (dir + 2)]); |
1697 | ret |= fire_bow (op, op, NULL, dir, -5, op->x + freearr_x[absdir (dir - 2)], op->y + freearr_y[absdir (dir - 2)]); |
1680 | ret |= fire_bow (op, op, NULL, dir, -5, op->x + freearr_x[absdir (dir - 2)], op->y + freearr_y[absdir (dir - 2)]); |
1698 | } |
1681 | } |
1699 | else if (op->contr->bowtype == bow_spreadshot) |
1682 | else if (op->contr->bowtype == bow_spreadshot) |
1700 | { |
1683 | { |
1701 | ret |= fire_bow (op, op, NULL, dir, 0, op->x, op->y); |
1684 | ret = fire_bow (op, op, NULL, dir, 0, op->x, op->y); |
1702 | ret |= fire_bow (op, op, NULL, absdir (dir - 1), -5, op->x, op->y); |
1685 | ret |= fire_bow (op, op, NULL, absdir (dir - 1), -5, op->x, op->y); |
1703 | ret |= fire_bow (op, op, NULL, absdir (dir + 1), -5, op->x, op->y); |
1686 | ret |= fire_bow (op, op, NULL, absdir (dir + 1), -5, op->x, op->y); |
1704 | } |
1687 | } |
1705 | else |
1688 | else |
1706 | { |
1689 | { |
… | |
… | |
1763 | } |
1746 | } |
1764 | } |
1747 | } |
1765 | |
1748 | |
1766 | if (cast_spell (op, item, dir, item->inv, NULL)) |
1749 | if (cast_spell (op, item, dir, item->inv, NULL)) |
1767 | { |
1750 | { |
1768 | SET_FLAG (op, FLAG_BEEN_APPLIED); /* You now know something about it */ |
1751 | item->flag [FLAG_BEEN_APPLIED] = true; /* You now know something about it */ |
|
|
1752 | |
1769 | if (item->type == WAND) |
1753 | if (item->type == WAND) |
1770 | { |
1754 | { |
1771 | if (!(--item->stats.food)) |
1755 | if (!(--item->stats.food)) |
1772 | { |
1756 | { |
1773 | object *tmp; |
1757 | object *tmp; |
… | |
… | |
1793 | bool |
1777 | bool |
1794 | fire (object *op, int dir) |
1778 | fire (object *op, int dir) |
1795 | { |
1779 | { |
1796 | int spellcost = 0; |
1780 | int spellcost = 0; |
1797 | |
1781 | |
1798 | /* check for loss of invisiblity/hide */ |
|
|
1799 | if (action_makes_visible (op)) |
|
|
1800 | make_visible (op); |
|
|
1801 | |
|
|
1802 | player *pl = op->contr; |
1782 | player *pl = op->contr; |
1803 | |
1783 | |
1804 | if (pl->golem) |
1784 | if (pl->golem) |
1805 | { |
1785 | { |
1806 | control_golem (op->contr->golem, dir); |
1786 | control_golem (op->contr->golem, dir); |
… | |
… | |
1808 | } |
1788 | } |
1809 | |
1789 | |
1810 | object *ob = pl->ranged_ob; |
1790 | object *ob = pl->ranged_ob; |
1811 | |
1791 | |
1812 | if (!ob) |
1792 | if (!ob) |
1813 | return false; |
|
|
1814 | |
|
|
1815 | if (!op->change_weapon (ob)) |
|
|
1816 | return false; |
1793 | return false; |
1817 | |
1794 | |
1818 | if (op->speed_left > 0.f) |
1795 | if (op->speed_left > 0.f) |
1819 | --op->speed_left; |
1796 | --op->speed_left; |
1820 | else |
1797 | else |
1821 | return false; |
1798 | return false; |
|
|
1799 | |
|
|
1800 | if (!op->change_weapon (ob)) |
|
|
1801 | return false; |
|
|
1802 | |
|
|
1803 | /* check for loss of invisiblity/hide */ |
|
|
1804 | if (action_makes_visible (op)) |
|
|
1805 | make_visible (op); |
1822 | |
1806 | |
1823 | switch (ob->type) |
1807 | switch (ob->type) |
1824 | { |
1808 | { |
1825 | case BOW: |
1809 | case BOW: |
1826 | player_fire_bow (op, dir); |
1810 | player_fire_bow (op, dir); |
… | |
… | |
2071 | --op->speed_left; |
2055 | --op->speed_left; |
2072 | |
2056 | |
2073 | op->play_sound (sound_find ("push_player")); |
2057 | op->play_sound (sound_find ("push_player")); |
2074 | push_ob (mon, dir, op); |
2058 | push_ob (mon, dir, op); |
2075 | |
2059 | |
2076 | if (op->contr->tmp_invis || op->hide) |
2060 | if (action_makes_visible (op)) |
2077 | make_visible (op); |
2061 | make_visible (op); |
2078 | |
2062 | |
2079 | return true; |
2063 | return true; |
2080 | } |
2064 | } |
2081 | else |
2065 | else |
… | |
… | |
2103 | push_ob (mon, dir, op); |
2087 | push_ob (mon, dir, op); |
2104 | } |
2088 | } |
2105 | else |
2089 | else |
2106 | op->statusmsg ("You withhold your attack"); |
2090 | op->statusmsg ("You withhold your attack"); |
2107 | |
2091 | |
2108 | if (op->contr->tmp_invis || op->hide) |
2092 | if (op->contr->tmp_invis || op->flag [FLAG_HIDDEN]) |
2109 | make_visible (op); |
2093 | make_visible (op); |
2110 | |
2094 | |
2111 | return true; |
2095 | return true; |
2112 | } |
2096 | } |
2113 | } |
2097 | } |
… | |
… | |
2171 | if (QUERY_FLAG (op, FLAG_CONFUSED) && dir) |
2155 | if (QUERY_FLAG (op, FLAG_CONFUSED) && dir) |
2172 | dir = absdir (dir + rndm (3) + rndm (3) - 2); |
2156 | dir = absdir (dir + rndm (3) + rndm (3) - 2); |
2173 | |
2157 | |
2174 | op->facing = dir; |
2158 | op->facing = dir; |
2175 | |
2159 | |
2176 | if (op->hide) |
2160 | if (op->flag [FLAG_HIDDEN]) |
2177 | do_hidden_move (op); |
2161 | do_hidden_move (op); |
2178 | |
2162 | |
2179 | bool retval; |
2163 | bool retval; |
2180 | |
2164 | |
2181 | if (INVOKE_PLAYER (MOVE, op->contr, ARG_INT (dir))) |
2165 | if (INVOKE_PLAYER (MOVE, op->contr, ARG_INT (dir))) |
… | |
… | |
2253 | if (QUERY_FLAG (tmp, FLAG_APPLIED) && QUERY_FLAG (tmp, FLAG_LIFESAVE)) |
2237 | if (QUERY_FLAG (tmp, FLAG_APPLIED) && QUERY_FLAG (tmp, FLAG_LIFESAVE)) |
2254 | { |
2238 | { |
2255 | op->play_sound (sound_find ("ob_evaporate")); |
2239 | op->play_sound (sound_find ("ob_evaporate")); |
2256 | new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s vibrates violently, then evaporates.", query_name (tmp)); |
2240 | new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s vibrates violently, then evaporates.", query_name (tmp)); |
2257 | |
2241 | |
2258 | tmp->destroy (true); |
2242 | tmp->destroy (); |
2259 | CLEAR_FLAG (op, FLAG_LIFESAVE); |
2243 | CLEAR_FLAG (op, FLAG_LIFESAVE); |
2260 | |
2244 | |
2261 | if (op->stats.hp < 0) |
2245 | if (op->stats.hp < 0) |
2262 | op->stats.hp = op->stats.maxhp; |
2246 | op->stats.hp = op->stats.maxhp; |
2263 | |
2247 | |
… | |
… | |
2499 | { |
2483 | { |
2500 | over_hp = (gen_hp < 20 ? 30 : gen_hp + 10) / rate_hp; |
2484 | over_hp = (gen_hp < 20 ? 30 : gen_hp + 10) / rate_hp; |
2501 | |
2485 | |
2502 | if (over_hp > 0) |
2486 | if (over_hp > 0) |
2503 | { |
2487 | { |
2504 | op->stats.sp += over_hp + (RANDOM () % rate_hp > ((gen_hp < 20 ? 30 : gen_hp + 10) % rate_hp)) ? -1 : 0; |
2488 | op->stats.sp += over_hp + (rndm (rate_hp) > ((gen_hp < 20 ? 30 : gen_hp + 10) % rate_hp)) ? -1 : 0; |
2505 | op->last_heal = 0; |
2489 | op->last_heal = 0; |
2506 | } |
2490 | } |
2507 | else |
2491 | else |
2508 | op->last_heal = rate_hp / (gen_hp < 20 ? 30 : gen_hp + 10); |
2492 | op->last_heal = rate_hp / (gen_hp < 20 ? 30 : gen_hp + 10); |
2509 | } |
2493 | } |
… | |
… | |
2569 | op->stats.food = 0; |
2553 | op->stats.food = 0; |
2570 | |
2554 | |
2571 | if (op->stats.hp < 0) |
2555 | if (op->stats.hp < 0) |
2572 | { |
2556 | { |
2573 | op->contr->killer = archetype::get ("killer_starvation"); |
2557 | op->contr->killer = archetype::get ("killer_starvation"); |
2574 | op->contr->killer->destroy (true); |
2558 | op->contr->killer->destroy (); |
2575 | } |
2559 | } |
2576 | } |
2560 | } |
2577 | |
2561 | |
2578 | /* killer should be set here already */ |
2562 | /* killer should be set here already */ |
2579 | if (op->stats.hp < 0 && !QUERY_FLAG (op, FLAG_WIZ)) |
2563 | if (op->stats.hp < 0 && !QUERY_FLAG (op, FLAG_WIZ)) |
… | |
… | |
2610 | |
2594 | |
2611 | /* restore player */ |
2595 | /* restore player */ |
2612 | at = archetype::find ("poisoning"); |
2596 | at = archetype::find ("poisoning"); |
2613 | if (object *tmp = present_arch_in_ob (at, op)) |
2597 | if (object *tmp = present_arch_in_ob (at, op)) |
2614 | { |
2598 | { |
2615 | tmp->destroy (true); |
2599 | tmp->destroy (); |
2616 | new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed"); |
2600 | new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed"); |
2617 | } |
2601 | } |
2618 | |
2602 | |
2619 | at = archetype::find ("confusion"); |
2603 | at = archetype::find ("confusion"); |
2620 | if (object *tmp = present_arch_in_ob (at, op)) |
2604 | if (object *tmp = present_arch_in_ob (at, op)) |
2621 | { |
2605 | { |
2622 | tmp->destroy (true); |
2606 | tmp->destroy (); |
2623 | new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); |
2607 | new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); |
2624 | } |
2608 | } |
2625 | |
2609 | |
2626 | cure_disease (op, 0, 0); /* remove any disease */ |
2610 | cure_disease (op, 0, 0); /* remove any disease */ |
2627 | op->stats.hp = op->stats.maxhp; |
2611 | op->stats.hp = op->stats.maxhp; |
… | |
… | |
2690 | |
2674 | |
2691 | lost_a_stat = 0; |
2675 | lost_a_stat = 0; |
2692 | |
2676 | |
2693 | for (z = 0; z < num_stats_lose; z++) |
2677 | for (z = 0; z < num_stats_lose; z++) |
2694 | { |
2678 | { |
2695 | i = RANDOM () % NUM_STATS; |
2679 | i = rndm (NUM_STATS); |
2696 | |
2680 | |
2697 | if (settings.stat_loss_on_death) |
2681 | if (settings.stat_loss_on_death) |
2698 | { |
2682 | { |
2699 | /* Pick a random stat and take a point off it. Tell the player |
2683 | /* Pick a random stat and take a point off it. Tell the player |
2700 | * what he lost. |
2684 | * what he lost. |
… | |
… | |
2812 | at = archetype::find ("poisoning"); |
2796 | at = archetype::find ("poisoning"); |
2813 | tmp = present_arch_in_ob (at, op); |
2797 | tmp = present_arch_in_ob (at, op); |
2814 | |
2798 | |
2815 | if (tmp) |
2799 | if (tmp) |
2816 | { |
2800 | { |
2817 | tmp->destroy (true); |
2801 | tmp->destroy (); |
2818 | new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed"); |
2802 | new_draw_info (NDI_UNIQUE, 0, op, "Your body feels cleansed"); |
2819 | } |
2803 | } |
2820 | |
2804 | |
2821 | at = archetype::find ("confusion"); |
2805 | at = archetype::find ("confusion"); |
2822 | tmp = present_arch_in_ob (at, op); |
2806 | tmp = present_arch_in_ob (at, op); |
2823 | if (tmp) |
2807 | if (tmp) |
2824 | { |
2808 | { |
2825 | tmp->destroy (true); |
2809 | tmp->destroy (); |
2826 | new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); |
2810 | new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); |
2827 | } |
2811 | } |
2828 | |
2812 | |
2829 | cure_disease (op, 0, 0); /* remove any disease */ |
2813 | cure_disease (op, 0, 0); /* remove any disease */ |
2830 | |
2814 | |
… | |
… | |
2833 | for (object *item = op->inv; item; ) |
2817 | for (object *item = op->inv; item; ) |
2834 | { |
2818 | { |
2835 | object *next = item->below; |
2819 | object *next = item->below; |
2836 | |
2820 | |
2837 | if (item->type == SPELL_EFFECT && item->active) |
2821 | if (item->type == SPELL_EFFECT && item->active) |
2838 | item->destroy (true); |
2822 | item->destroy (); |
2839 | |
2823 | |
2840 | item = next; |
2824 | item = next; |
2841 | } |
2825 | } |
2842 | |
2826 | |
2843 | /*add_exp(op, (op->stats.exp * -0.20)); */ |
2827 | /*add_exp(op, (op->stats.exp * -0.20)); */ |
… | |
… | |
2924 | { |
2908 | { |
2925 | tmp->decrease (rndm (1, tmp->nrof - 1)); |
2909 | tmp->decrease (rndm (1, tmp->nrof - 1)); |
2926 | insert_ob_in_map (tmp, op->map, NULL, 0); |
2910 | insert_ob_in_map (tmp, op->map, NULL, 0); |
2927 | } |
2911 | } |
2928 | else |
2912 | else |
2929 | tmp->destroy (true); |
2913 | tmp->destroy (); |
2930 | } |
2914 | } |
2931 | else |
2915 | else |
2932 | insert_ob_in_map (tmp, op->map, NULL, 0); |
2916 | insert_ob_in_map (tmp, op->map, NULL, 0); |
2933 | } |
2917 | } |
2934 | } |
2918 | } |
… | |
… | |
2995 | if (op->type == PLAYER) |
2979 | if (op->type == PLAYER) |
2996 | new_draw_info_format (NDI_UNIQUE, 0, op, "You cast %s.", &spob->name); |
2980 | new_draw_info_format (NDI_UNIQUE, 0, op, "You cast %s.", &spob->name); |
2997 | |
2981 | |
2998 | cast_spell (op, throw_ob, dir, spob, NULL); |
2982 | cast_spell (op, throw_ob, dir, spob, NULL); |
2999 | |
2983 | |
3000 | throw_ob->destroy (true); |
2984 | throw_ob->destroy (); |
3001 | } |
2985 | } |
3002 | |
2986 | |
3003 | void |
2987 | void |
3004 | make_visible (object *op) |
2988 | make_visible (object *op) |
3005 | { |
2989 | { |
3006 | op->hide = 0; |
2990 | op->flag [FLAG_HIDDEN] = 0; |
3007 | op->invisible = 0; |
2991 | op->invisible = 0; |
3008 | |
2992 | |
3009 | if (op->type == PLAYER) |
2993 | if (op->type == PLAYER) |
3010 | { |
2994 | { |
3011 | op->contr->tmp_invis = 0; |
2995 | op->contr->tmp_invis = 0; |
… | |
… | |
3036 | |
3020 | |
3037 | if (!ob || !ob->map) |
3021 | if (!ob || !ob->map) |
3038 | return 0; |
3022 | return 0; |
3039 | |
3023 | |
3040 | /* so, on normal lighted maps, its hard to hide */ |
3024 | /* so, on normal lighted maps, its hard to hide */ |
3041 | level = ob->map->darkness - 2; |
3025 | level = ob->map->darklevel () - 2; |
3042 | |
3026 | |
3043 | /* this also picks up whether the object is glowing. |
3027 | /* this also picks up whether the object is glowing. |
3044 | * If you carry a light on a non-dark map, its not |
3028 | * If you carry a light on a non-dark map, its not |
3045 | * as bad as carrying a light on a pitch dark map */ |
3029 | * as bad as carrying a light on a pitch dark map */ |
3046 | if (has_carried_lights (ob)) |
3030 | if (has_carried_lights (ob)) |
3047 | level = -(10 + (2 * ob->map->darkness)); |
3031 | level = -(10 + (2 * ob->map->darklevel ())); |
3048 | |
3032 | |
3049 | /* scan through all nearby squares for terrain to hide in */ |
3033 | /* scan through all nearby squares for terrain to hide in */ |
3050 | for (i = 0, x = ob->x, y = ob->y; |
3034 | for (i = 0, x = ob->x, y = ob->y; |
3051 | i <= SIZEOFFREE1; |
3035 | i <= SIZEOFFREE1; |
3052 | i++, x = ob->x + freearr_x[i], y = ob->y + freearr_y[i]) |
3036 | i++, x = ob->x + freearr_x[i], y = ob->y + freearr_y[i]) |
… | |
… | |
3199 | while (op) |
3183 | while (op) |
3200 | { |
3184 | { |
3201 | dx = rv.distance_x + op->arch->x; |
3185 | dx = rv.distance_x + op->arch->x; |
3202 | dy = rv.distance_y + op->arch->y; |
3186 | dy = rv.distance_y + op->arch->y; |
3203 | |
3187 | |
3204 | /* only the viewable area the player sees is updated by LOS |
3188 | if (pl->contr->blocked_los (dx, dy) != LOS_BLOCKED) |
3205 | * code, so we need to restrict ourselves to that range of values |
|
|
3206 | * for any meaningful values. |
|
|
3207 | */ |
|
|
3208 | if (abs (dx) <= (pl->contr->ns->mapx / 2) && |
|
|
3209 | abs (dy) <= (pl->contr->ns->mapy / 2) && |
|
|
3210 | !pl->contr->blocked_los[dx + (pl->contr->ns->mapx / 2)][dy + (pl->contr->ns->mapy / 2)]) |
|
|
3211 | return 1; |
3189 | return 1; |
3212 | |
3190 | |
3213 | op = op->more; |
3191 | op = op->more; |
3214 | } |
3192 | } |
3215 | |
3193 | |
3216 | return 0; |
3194 | return 0; |
3217 | } |
3195 | } |
3218 | |
3196 | |
3219 | /* routine for both players and monsters. We call this when |
3197 | /* routine for both players and monsters. We call this when |
3220 | * there is a possibility for our action distrubing our hiding |
3198 | * there is a possibility for our action distrubing our hiding |
3221 | * place or invisiblity spell. Artefact invisiblity is not |
3199 | * place or invisiblity spell. Artefact invisiblity causes |
3222 | * effected by this. If we arent invisible to begin with, we |
3200 | * "noise" instead. If we arent invisible to begin with, we |
3223 | * return 0. |
3201 | * return 0. |
3224 | */ |
3202 | */ |
3225 | int |
3203 | int |
3226 | action_makes_visible (object *op) |
3204 | action_makes_visible (object *op) |
3227 | { |
3205 | { |
3228 | if (op->invisible && QUERY_FLAG (op, FLAG_ALIVE)) |
3206 | if (op->invisible && QUERY_FLAG (op, FLAG_ALIVE)) |
3229 | { |
3207 | { |
3230 | if (QUERY_FLAG (op, FLAG_MAKE_INVIS)) |
3208 | if (QUERY_FLAG (op, FLAG_MAKE_INVIS)) |
|
|
3209 | { |
|
|
3210 | // artefact invisibility is permanent, but we still make noise |
|
|
3211 | // this is important for game-balance. |
|
|
3212 | if (op->contr) |
|
|
3213 | op->make_noise (); |
|
|
3214 | |
3231 | return 0; |
3215 | return 0; |
|
|
3216 | } |
3232 | |
3217 | |
3233 | if (op->contr && op->contr->tmp_invis == 0) |
3218 | if (op->contr && op->contr->tmp_invis == 0) |
3234 | return 0; |
3219 | return 0; |
3235 | |
3220 | |
3236 | /* If monsters, they should become visible */ |
3221 | /* If monsters, they should become visible */ |
3237 | if (op->hide || !op->contr || (op->contr && op->contr->tmp_invis)) |
3222 | if (op->flag [FLAG_HIDDEN] || !op->contr || (op->contr && op->contr->tmp_invis)) |
3238 | { |
3223 | { |
3239 | new_draw_info_format (NDI_UNIQUE, 0, op, "You become %s!", op->hide ? "unhidden" : "visible"); |
3224 | new_draw_info_format (NDI_UNIQUE, 0, op, "You become %s!", op->flag [FLAG_HIDDEN] ? "unhidden" : "visible"); |
3240 | return 1; |
3225 | return 1; |
3241 | } |
3226 | } |
3242 | } |
3227 | } |
3243 | |
3228 | |
3244 | return 0; |
3229 | return 0; |
… | |
… | |
3472 | if (pl->ranged_ob == ob) |
3457 | if (pl->ranged_ob == ob) |
3473 | pl->ranged_ob = 0; |
3458 | pl->ranged_ob = 0; |
3474 | } |
3459 | } |
3475 | |
3460 | |
3476 | sint8 |
3461 | sint8 |
3477 | player::visibility_at (maptile *map, int x, int y) const |
3462 | player::darkness_at (maptile *map, int x, int y) const |
3478 | { |
3463 | { |
3479 | if (!ns) |
3464 | if (!ns) |
3480 | return 0; |
3465 | return LOS_BLOCKED; |
3481 | |
3466 | |
3482 | int dx, dy; |
3467 | int dx, dy; |
3483 | if (!adjacent_map (map, ns->current_map, &dx, &dy)) |
3468 | if (!adjacent_map (map, ns->current_map, &dx, &dy)) |
3484 | return 0; |
3469 | return LOS_BLOCKED; |
3485 | |
3470 | |
3486 | x += dx - ns->current_x + ns->mapx / 2; |
3471 | x += dx - ns->current_x; |
3487 | y += dy - ns->current_y + ns->mapy / 2; |
3472 | y += dy - ns->current_y; |
3488 | |
3473 | |
3489 | if (!IN_RANGE_EXC (x, 0, ns->mapx) || !IN_RANGE_EXC (y, 0, ns->mapy)) |
|
|
3490 | return 0; |
|
|
3491 | |
|
|
3492 | return 100 - blocked_los [x][y]; |
3474 | return blocked_los (x, y); |
3493 | } |
3475 | } |
3494 | |
3476 | |
3495 | void |
3477 | void |
3496 | player::infobox (const char *title, const char *msg, int color) |
3478 | player::infobox (const char *title, const char *msg, int color) |
3497 | { |
3479 | { |