1 | |
1 | |
2 | /* |
2 | /* |
3 | * static char *rcsid_apply_c = |
3 | * static char *rcsid_apply_c = |
4 | * "$Id: apply.C,v 1.23 2006/09/11 11:46:52 root Exp $"; |
4 | * "$Id: apply.C,v 1.24 2006/09/11 20:26:41 root Exp $"; |
5 | */ |
5 | */ |
6 | |
6 | |
7 | /* |
7 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
8 | CrossFire, A Multiplayer game for X-windows |
9 | |
9 | |
… | |
… | |
737 | eat_item (op, improver->slaying, sacrifice_needed); |
737 | eat_item (op, improver->slaying, sacrifice_needed); |
738 | weapon->item_power++; |
738 | weapon->item_power++; |
739 | |
739 | |
740 | switch (improver->stats.sp) |
740 | switch (improver->stats.sp) |
741 | { |
741 | { |
742 | case IMPROVE_STR: |
742 | case IMPROVE_STR: |
743 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Str), 1, "strength"); |
743 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Str), 1, "strength"); |
744 | case IMPROVE_DEX: |
744 | case IMPROVE_DEX: |
745 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Dex), 1, "dexterity"); |
745 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Dex), 1, "dexterity"); |
746 | case IMPROVE_CON: |
746 | case IMPROVE_CON: |
747 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Con), 1, "constitution"); |
747 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Con), 1, "constitution"); |
748 | case IMPROVE_WIS: |
748 | case IMPROVE_WIS: |
749 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Wis), 1, "wisdom"); |
749 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Wis), 1, "wisdom"); |
750 | case IMPROVE_CHA: |
750 | case IMPROVE_CHA: |
751 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Cha), 1, "charisma"); |
751 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Cha), 1, "charisma"); |
752 | case IMPROVE_INT: |
752 | case IMPROVE_INT: |
753 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Int), 1, "intelligence"); |
753 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Int), 1, "intelligence"); |
754 | case IMPROVE_POW: |
754 | case IMPROVE_POW: |
755 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Pow), 1, "power"); |
755 | return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Pow), 1, "power"); |
756 | default: |
756 | default: |
757 | new_draw_info (NDI_UNIQUE, 0, op, "Unknown improvement type."); |
757 | new_draw_info (NDI_UNIQUE, 0, op, "Unknown improvement type."); |
758 | } |
758 | } |
759 | LOG (llevError, "improve_weapon: Got to end of function\n"); |
759 | LOG (llevError, "improve_weapon: Got to end of function\n"); |
760 | return 0; |
760 | return 0; |
761 | } |
761 | } |
762 | |
762 | |
… | |
… | |
1323 | { |
1323 | { |
1324 | return 0; |
1324 | return 0; |
1325 | } |
1325 | } |
1326 | } |
1326 | } |
1327 | |
1327 | |
1328 | |
|
|
1329 | /** |
1328 | /** |
1330 | * Handles 'movement' of shop mats. |
1329 | * Handles 'movement' of shop mats. |
1331 | * Returns 1 if 'op' was destroyed, 0 if not. |
1330 | * Returns 1 if 'op' was destroyed, 0 if not. |
1332 | * Largely re-written to not use nearly as many gotos, plus |
1331 | * Largely re-written to not use nearly as many gotos, plus |
1333 | * some of this code just looked plain out of date. |
1332 | * some of this code just looked plain out of date. |
… | |
… | |
1354 | if (QUERY_FLAG (tmp, FLAG_UNPAID)) |
1353 | if (QUERY_FLAG (tmp, FLAG_UNPAID)) |
1355 | { |
1354 | { |
1356 | int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); |
1355 | int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); |
1357 | |
1356 | |
1358 | remove_ob (tmp); |
1357 | remove_ob (tmp); |
|
|
1358 | |
1359 | if (i == -1) |
1359 | if (i == -1) |
1360 | i = 0; |
1360 | i = 0; |
|
|
1361 | |
1361 | tmp->map = op->map; |
1362 | tmp->map = op->map; |
1362 | tmp->x = op->x + freearr_x[i]; |
1363 | tmp->x = op->x + freearr_x[i]; |
1363 | tmp->y = op->y + freearr_y[i]; |
1364 | tmp->y = op->y + freearr_y[i]; |
1364 | insert_ob_in_map (tmp, op->map, op, 0); |
1365 | insert_ob_in_map (tmp, op->map, op, 0); |
1365 | } |
1366 | } |
… | |
… | |
1377 | |
1378 | |
1378 | /* Somebody dropped an unpaid item, just move to an adjacent place. */ |
1379 | /* Somebody dropped an unpaid item, just move to an adjacent place. */ |
1379 | int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); |
1380 | int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); |
1380 | |
1381 | |
1381 | if (i != -1) |
1382 | if (i != -1) |
1382 | { |
|
|
1383 | rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat); |
1383 | rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat); |
1384 | } |
1384 | |
1385 | return 0; |
1385 | return 0; |
1386 | } |
1386 | } |
1387 | /* Removed code that checked for multipart objects - it appears that |
1387 | /* Removed code that checked for multipart objects - it appears that |
1388 | * the teleport function should be able to handle this just fine. |
1388 | * the teleport function should be able to handle this just fine. |
1389 | */ |
1389 | */ |
1390 | rv = teleport (shop_mat, SHOP_MAT, op); |
1390 | rv = teleport (shop_mat, SHOP_MAT, op); |
1391 | } |
1391 | } |
1392 | /* immediate block below is only used for players */ |
|
|
1393 | else if (can_pay (op)) |
1392 | else if (can_pay (op)) |
1394 | { |
1393 | { |
|
|
1394 | /* this is only used for players */ |
1395 | get_payment (op, op->inv); |
1395 | get_payment (op, op->inv); |
1396 | rv = teleport (shop_mat, SHOP_MAT, op); |
1396 | rv = teleport (shop_mat, SHOP_MAT, op); |
1397 | |
1397 | |
1398 | if (shop_mat->msg) |
1398 | if (shop_mat->msg) |
1399 | { |
|
|
1400 | new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg); |
1399 | new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg); |
1401 | } |
|
|
1402 | /* This check below is a bit simplistic - generally it should be correct, |
1400 | /* This check below is a bit simplistic - generally it should be correct, |
1403 | * but there is never a guarantee that the bottom space on the map is |
1401 | * but there is never a guarantee that the bottom space on the map is |
1404 | * actually the shop floor. |
1402 | * actually the shop floor. |
1405 | */ |
1403 | */ |
1406 | else if (!rv && !is_in_shop (op)) |
1404 | else if (!rv && !is_in_shop (op)) |
1407 | { |
1405 | { |
1408 | opinion = shopkeeper_approval (op->map, op); |
1406 | opinion = shopkeeper_approval (op->map, op); |
|
|
1407 | |
1409 | if (opinion > 0.9) |
1408 | if (opinion > 0.9) |
1410 | new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper gives you a friendly wave."); |
1409 | new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper gives you a friendly wave."); |
1411 | else if (opinion > 0.75) |
1410 | else if (opinion > 0.75) |
1412 | new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper waves to you."); |
1411 | new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper waves to you."); |
1413 | else if (opinion > 0.5) |
1412 | else if (opinion > 0.5) |
… | |
… | |
1435 | op->x += freearr_x[i]; |
1434 | op->x += freearr_x[i]; |
1436 | op->y += freearr_y[i]; |
1435 | op->y += freearr_y[i]; |
1437 | rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL; |
1436 | rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL; |
1438 | } |
1437 | } |
1439 | } |
1438 | } |
|
|
1439 | |
1440 | CLEAR_FLAG (op, FLAG_NO_APPLY); |
1440 | CLEAR_FLAG (op, FLAG_NO_APPLY); |
1441 | return rv; |
1441 | return rv; |
1442 | } |
1442 | } |
1443 | |
1443 | |
1444 | /** |
1444 | /** |
… | |
… | |
1707 | apply_id_altar (victim, trap, originator); |
1707 | apply_id_altar (victim, trap, originator); |
1708 | goto leave; |
1708 | goto leave; |
1709 | |
1709 | |
1710 | case SIGN: |
1710 | case SIGN: |
1711 | if (victim->type != PLAYER && trap->stats.food > 0) |
1711 | if (victim->type != PLAYER && trap->stats.food > 0) |
1712 | goto leave; /* monsters musn't apply magic_mouths with counters */ |
1712 | goto leave; /* monsters musn't apply magic_mouths with counters */ |
1713 | |
1713 | |
1714 | apply_sign (victim, trap, 1); |
1714 | apply_sign (victim, trap, 1); |
1715 | goto leave; |
1715 | goto leave; |
1716 | |
1716 | |
1717 | case CONTAINER: |
1717 | case CONTAINER: |
… | |
… | |
1817 | static void |
1817 | static void |
1818 | apply_skillscroll (object *op, object *tmp) |
1818 | apply_skillscroll (object *op, object *tmp) |
1819 | { |
1819 | { |
1820 | switch ((int) learn_skill (op, tmp)) |
1820 | switch ((int) learn_skill (op, tmp)) |
1821 | { |
1821 | { |
1822 | case 0: |
1822 | case 0: |
1823 | new_draw_info (NDI_UNIQUE, 0, op, "You already possess the knowledge "); |
1823 | new_draw_info (NDI_UNIQUE, 0, op, "You already possess the knowledge "); |
1824 | new_draw_info_format (NDI_UNIQUE, 0, op, "held within the %s.\n", query_name (tmp)); |
1824 | new_draw_info_format (NDI_UNIQUE, 0, op, "held within the %s.\n", query_name (tmp)); |
1825 | return; |
1825 | return; |
1826 | |
1826 | |
1827 | case 1: |
1827 | case 1: |
1828 | new_draw_info_format (NDI_UNIQUE, 0, op, "You succeed in learning %s", &tmp->skill); |
1828 | new_draw_info_format (NDI_UNIQUE, 0, op, "You succeed in learning %s", &tmp->skill); |
1829 | decrease_ob (tmp); |
1829 | decrease_ob (tmp); |
1830 | return; |
1830 | return; |
1831 | |
1831 | |
1832 | default: |
1832 | default: |
1833 | new_draw_info_format (NDI_UNIQUE, 0, op, "You fail to learn the knowledge of the %s.\n", query_name (tmp)); |
1833 | new_draw_info_format (NDI_UNIQUE, 0, op, "You fail to learn the knowledge of the %s.\n", query_name (tmp)); |
1834 | decrease_ob (tmp); |
1834 | decrease_ob (tmp); |
1835 | return; |
1835 | return; |
1836 | } |
1836 | } |
1837 | } |
1837 | } |
1838 | |
1838 | |
1839 | /** |
1839 | /** |
1840 | * Actually makes op learn spell. |
1840 | * Actually makes op learn spell. |
… | |
… | |
2568 | return RESULT_INT (0); |
2568 | return RESULT_INT (0); |
2569 | |
2569 | |
2570 | switch (tmp->type) |
2570 | switch (tmp->type) |
2571 | { |
2571 | { |
2572 | |
2572 | |
2573 | case CF_HANDLE: |
2573 | case CF_HANDLE: |
2574 | new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); |
2574 | new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); |
2575 | play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE); |
2575 | play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE); |
2576 | tmp->value = tmp->value ? 0 : 1; |
2576 | tmp->value = tmp->value ? 0 : 1; |
2577 | SET_ANIMATION (tmp, tmp->value); |
2577 | SET_ANIMATION (tmp, tmp->value); |
2578 | update_object (tmp, UP_OBJ_FACE); |
2578 | update_object (tmp, UP_OBJ_FACE); |
2579 | push_button (tmp); |
2579 | push_button (tmp); |
2580 | return 1; |
2580 | return 1; |
2581 | |
2581 | |
2582 | case TRIGGER: |
2582 | case TRIGGER: |
2583 | if (check_trigger (tmp, op)) |
2583 | if (check_trigger (tmp, op)) |
2584 | { |
2584 | { |
2585 | new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); |
2585 | new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); |
2586 | play_sound_map (tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE); |
2586 | play_sound_map (tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE); |
2587 | } |
2587 | } |
2588 | else |
2588 | else |
2589 | { |
2589 | { |
2590 | new_draw_info (NDI_UNIQUE, 0, op, "The handle doesn't move."); |
2590 | new_draw_info (NDI_UNIQUE, 0, op, "The handle doesn't move."); |
2591 | } |
2591 | } |
2592 | return 1; |
2592 | return 1; |
2593 | |
2593 | |
2594 | case EXIT: |
2594 | case EXIT: |
2595 | if (op->type != PLAYER) |
2595 | if (op->type != PLAYER) |
|
|
2596 | return 0; |
|
|
2597 | if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp)) |
|
|
2598 | { |
|
|
2599 | new_draw_info_format (NDI_UNIQUE, 0, op, "The %s is closed.", query_name (tmp)); |
|
|
2600 | } |
|
|
2601 | else |
|
|
2602 | { |
|
|
2603 | /* Don't display messages for random maps. */ |
|
|
2604 | if (tmp->msg && strncmp (EXIT_PATH (tmp), "/!", 2) && strncmp (EXIT_PATH (tmp), "/random/", 8)) |
|
|
2605 | new_draw_info (NDI_NAVY, 0, op, tmp->msg); |
|
|
2606 | enter_exit (op, tmp); |
|
|
2607 | } |
|
|
2608 | return 1; |
|
|
2609 | |
|
|
2610 | case SIGN: |
|
|
2611 | apply_sign (op, tmp, 0); |
|
|
2612 | return 1; |
|
|
2613 | |
|
|
2614 | case BOOK: |
|
|
2615 | if (op->type == PLAYER) |
|
|
2616 | { |
|
|
2617 | apply_book (op, tmp); |
|
|
2618 | return 1; |
|
|
2619 | } |
|
|
2620 | else |
|
|
2621 | { |
2596 | return 0; |
2622 | return 0; |
2597 | if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp)) |
|
|
2598 | { |
|
|
2599 | new_draw_info_format (NDI_UNIQUE, 0, op, "The %s is closed.", query_name (tmp)); |
|
|
2600 | } |
2623 | } |
2601 | else |
|
|
2602 | { |
|
|
2603 | /* Don't display messages for random maps. */ |
|
|
2604 | if (tmp->msg && strncmp (EXIT_PATH (tmp), "/!", 2) && strncmp (EXIT_PATH (tmp), "/random/", 8)) |
|
|
2605 | new_draw_info (NDI_NAVY, 0, op, tmp->msg); |
|
|
2606 | enter_exit (op, tmp); |
|
|
2607 | } |
|
|
2608 | return 1; |
|
|
2609 | |
2624 | |
2610 | case SIGN: |
2625 | case SKILLSCROLL: |
2611 | apply_sign (op, tmp, 0); |
|
|
2612 | return 1; |
|
|
2613 | |
|
|
2614 | case BOOK: |
|
|
2615 | if (op->type == PLAYER) |
2626 | if (op->type == PLAYER) |
2616 | { |
2627 | { |
2617 | apply_book (op, tmp); |
|
|
2618 | return 1; |
|
|
2619 | } |
|
|
2620 | else |
|
|
2621 | { |
|
|
2622 | return 0; |
|
|
2623 | } |
|
|
2624 | |
|
|
2625 | case SKILLSCROLL: |
|
|
2626 | if (op->type == PLAYER) |
|
|
2627 | { |
|
|
2628 | apply_skillscroll (op, tmp); |
2628 | apply_skillscroll (op, tmp); |
2629 | return 1; |
2629 | return 1; |
2630 | } |
2630 | } |
2631 | return 0; |
2631 | return 0; |
2632 | |
2632 | |
2633 | case SPELLBOOK: |
2633 | case SPELLBOOK: |
2634 | if (op->type == PLAYER) |
2634 | if (op->type == PLAYER) |
2635 | { |
2635 | { |
2636 | apply_spellbook (op, tmp); |
2636 | apply_spellbook (op, tmp); |
2637 | return 1; |
2637 | return 1; |
2638 | } |
2638 | } |
2639 | return 0; |
2639 | return 0; |
2640 | |
2640 | |
2641 | case SCROLL: |
2641 | case SCROLL: |
2642 | apply_scroll (op, tmp, 0); |
2642 | apply_scroll (op, tmp, 0); |
2643 | return 1; |
2643 | return 1; |
2644 | |
2644 | |
2645 | case POTION: |
2645 | case POTION: |
2646 | (void) apply_potion (op, tmp); |
2646 | (void) apply_potion (op, tmp); |
2647 | return 1; |
2647 | return 1; |
2648 | |
2648 | |
2649 | /* Eneq(@csd.uu.se): Handle apply on containers. */ |
2649 | /* Eneq(@csd.uu.se): Handle apply on containers. */ |
2650 | case CLOSE_CON: |
2650 | case CLOSE_CON: |
2651 | if (op->type == PLAYER) |
2651 | if (op->type == PLAYER) |
2652 | (void) esrv_apply_container (op, tmp->env); |
2652 | (void) esrv_apply_container (op, tmp->env); |
2653 | else |
2653 | else |
2654 | (void) apply_container (op, tmp->env); |
2654 | (void) apply_container (op, tmp->env); |
2655 | return 1; |
2655 | return 1; |
2656 | |
2656 | |
2657 | case CONTAINER: |
2657 | case CONTAINER: |
2658 | if (op->type == PLAYER) |
2658 | if (op->type == PLAYER) |
2659 | (void) esrv_apply_container (op, tmp); |
2659 | (void) esrv_apply_container (op, tmp); |
2660 | else |
2660 | else |
2661 | (void) apply_container (op, tmp); |
2661 | (void) apply_container (op, tmp); |
2662 | return 1; |
2662 | return 1; |
2663 | |
2663 | |
2664 | case TREASURE: |
2664 | case TREASURE: |
2665 | if (op->type == PLAYER) |
2665 | if (op->type == PLAYER) |
2666 | { |
2666 | { |
2667 | apply_treasure (op, tmp); |
2667 | apply_treasure (op, tmp); |
2668 | return 1; |
2668 | return 1; |
2669 | } |
2669 | } |
2670 | else |
2670 | else |
2671 | { |
2671 | { |
2672 | return 0; |
2672 | return 0; |
2673 | } |
2673 | } |
2674 | |
2674 | |
2675 | case WEAPON: |
2675 | case WEAPON: |
2676 | case ARMOUR: |
2676 | case ARMOUR: |
2677 | case BOOTS: |
2677 | case BOOTS: |
2678 | case GLOVES: |
2678 | case GLOVES: |
2679 | case AMULET: |
2679 | case AMULET: |
2680 | case GIRDLE: |
2680 | case GIRDLE: |
2681 | case BRACERS: |
2681 | case BRACERS: |
2682 | case SHIELD: |
2682 | case SHIELD: |
2683 | case HELMET: |
2683 | case HELMET: |
2684 | case RING: |
2684 | case RING: |
2685 | case CLOAK: |
2685 | case CLOAK: |
2686 | case WAND: |
2686 | case WAND: |
2687 | case ROD: |
2687 | case ROD: |
2688 | case HORN: |
2688 | case HORN: |
2689 | case SKILL: |
2689 | case SKILL: |
2690 | case BOW: |
2690 | case BOW: |
2691 | case LAMP: |
2691 | case LAMP: |
2692 | case BUILDER: |
2692 | case BUILDER: |
2693 | case SKILL_TOOL: |
2693 | case SKILL_TOOL: |
2694 | if (tmp->env != op) |
2694 | if (tmp->env != op) |
2695 | return 2; /* not in inventory */ |
2695 | return 2; /* not in inventory */ |
2696 | (void) apply_special (op, tmp, aflag); |
2696 | (void) apply_special (op, tmp, aflag); |
2697 | return 1; |
2697 | return 1; |
2698 | |
2698 | |
2699 | case DRINK: |
2699 | case DRINK: |
2700 | case FOOD: |
2700 | case FOOD: |
2701 | case FLESH: |
2701 | case FLESH: |
2702 | apply_food (op, tmp); |
2702 | apply_food (op, tmp); |
2703 | return 1; |
2703 | return 1; |
2704 | |
2704 | |
2705 | case POISON: |
2705 | case POISON: |
2706 | apply_poison (op, tmp); |
2706 | apply_poison (op, tmp); |
2707 | return 1; |
2707 | return 1; |
2708 | |
2708 | |
2709 | case SAVEBED: |
2709 | case SAVEBED: |
2710 | if (op->type == PLAYER) |
2710 | if (op->type == PLAYER) |
2711 | { |
2711 | { |
2712 | apply_savebed (op); |
2712 | apply_savebed (op); |
2713 | return 1; |
2713 | return 1; |
2714 | } |
2714 | } |
2715 | else |
2715 | else |
2716 | { |
2716 | { |
2717 | return 0; |
2717 | return 0; |
2718 | } |
2718 | } |
2719 | |
2719 | |
2720 | case ARMOUR_IMPROVER: |
2720 | case ARMOUR_IMPROVER: |
2721 | if (op->type == PLAYER) |
2721 | if (op->type == PLAYER) |
2722 | { |
2722 | { |
2723 | apply_armour_improver (op, tmp); |
2723 | apply_armour_improver (op, tmp); |
2724 | return 1; |
2724 | return 1; |
2725 | } |
2725 | } |
2726 | else |
2726 | else |
2727 | { |
2727 | { |
2728 | return 0; |
2728 | return 0; |
2729 | } |
2729 | } |
2730 | |
2730 | |
2731 | case WEAPON_IMPROVER: |
2731 | case WEAPON_IMPROVER: |
2732 | (void) check_improve_weapon (op, tmp); |
2732 | (void) check_improve_weapon (op, tmp); |
2733 | return 1; |
2733 | return 1; |
2734 | |
2734 | |
2735 | case CLOCK: |
2735 | case CLOCK: |
2736 | if (op->type == PLAYER) |
2736 | if (op->type == PLAYER) |
2737 | { |
2737 | { |
2738 | char buf[MAX_BUF]; |
2738 | char buf[MAX_BUF]; |
2739 | timeofday_t tod; |
2739 | timeofday_t tod; |
2740 | |
2740 | |
2741 | get_tod (&tod); |
2741 | get_tod (&tod); |
2742 | sprintf (buf, "It is %d minute%s past %d o'clock %s", |
2742 | sprintf (buf, "It is %d minute%s past %d o'clock %s", |
2743 | tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"), |
2743 | tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"), |
2744 | ((tod.hour % 14 == 0) ? 14 : ((tod.hour) % 14)), ((tod.hour >= 14) ? "pm" : "am")); |
2744 | ((tod.hour % 14 == 0) ? 14 : ((tod.hour) % 14)), ((tod.hour >= 14) ? "pm" : "am")); |
2745 | play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0); |
2745 | play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0); |
2746 | new_draw_info (NDI_UNIQUE, 0, op, buf); |
2746 | new_draw_info (NDI_UNIQUE, 0, op, buf); |
2747 | return 1; |
2747 | return 1; |
2748 | } |
2748 | } |
2749 | else |
2749 | else |
2750 | { |
2750 | { |
2751 | return 0; |
2751 | return 0; |
2752 | } |
2752 | } |
2753 | |
2753 | |
2754 | case MENU: |
2754 | case MENU: |
2755 | if (op->type == PLAYER) |
2755 | if (op->type == PLAYER) |
2756 | { |
2756 | { |
2757 | shop_listing (op); |
2757 | shop_listing (op); |
2758 | return 1; |
2758 | return 1; |
2759 | } |
2759 | } |
2760 | else |
2760 | else |
2761 | { |
2761 | { |
2762 | return 0; |
2762 | return 0; |
2763 | } |
2763 | } |
2764 | |
2764 | |
2765 | case POWER_CRYSTAL: |
2765 | case POWER_CRYSTAL: |
2766 | apply_power_crystal (op, tmp); /* see egoitem.c */ |
2766 | apply_power_crystal (op, tmp); /* see egoitem.c */ |
2767 | return 1; |
2767 | return 1; |
2768 | |
2768 | |
2769 | case LIGHTER: /* for lighting torches/lanterns/etc */ |
2769 | case LIGHTER: /* for lighting torches/lanterns/etc */ |
2770 | if (op->type == PLAYER) |
2770 | if (op->type == PLAYER) |
2771 | { |
2771 | { |
2772 | apply_lighter (op, tmp); |
2772 | apply_lighter (op, tmp); |
2773 | return 1; |
2773 | return 1; |
2774 | } |
2774 | } |
2775 | else |
2775 | else |
2776 | { |
2776 | { |
2777 | return 0; |
2777 | return 0; |
2778 | } |
2778 | } |
2779 | |
2779 | |
2780 | case ITEM_TRANSFORMER: |
2780 | case ITEM_TRANSFORMER: |
2781 | apply_item_transformer (op, tmp); |
2781 | apply_item_transformer (op, tmp); |
2782 | return 1; |
2782 | return 1; |
2783 | |
2783 | |
2784 | default: |
2784 | default: |
2785 | return 0; |
2785 | return 0; |
2786 | } |
2786 | } |
2787 | } |
2787 | } |
2788 | |
2788 | |
2789 | |
2789 | |
2790 | /* quiet suppresses the "don't know how to apply" and "you must get it first" |
2790 | /* quiet suppresses the "don't know how to apply" and "you must get it first" |
… | |
… | |
2896 | object *tmp2; |
2896 | object *tmp2; |
2897 | |
2897 | |
2898 | CLEAR_FLAG (op, FLAG_APPLIED); |
2898 | CLEAR_FLAG (op, FLAG_APPLIED); |
2899 | switch (op->type) |
2899 | switch (op->type) |
2900 | { |
2900 | { |
2901 | case WEAPON: |
2901 | case WEAPON: |
2902 | new_draw_info_format (NDI_UNIQUE, 0, who, "You unwield %s.", query_name (op)); |
2902 | new_draw_info_format (NDI_UNIQUE, 0, who, "You unwield %s.", query_name (op)); |
2903 | |
2903 | |
2904 | (void) change_abil (who, op); |
2904 | (void) change_abil (who, op); |
2905 | if (QUERY_FLAG (who, FLAG_READY_WEAPON)) |
2905 | if (QUERY_FLAG (who, FLAG_READY_WEAPON)) |
2906 | CLEAR_FLAG (who, FLAG_READY_WEAPON); |
2906 | CLEAR_FLAG (who, FLAG_READY_WEAPON); |
2907 | clear_skill (who); |
2907 | clear_skill (who); |
2908 | break; |
2908 | break; |
2909 | |
2909 | |
2910 | case SKILL: /* allows objects to impart skills */ |
2910 | case SKILL: /* allows objects to impart skills */ |
2911 | case SKILL_TOOL: |
2911 | case SKILL_TOOL: |
2912 | if (op != who->chosen_skill) |
2912 | if (op != who->chosen_skill) |
2913 | { |
2913 | { |
2914 | LOG (llevError, "BUG: apply_special(): applied skill is not a chosen skill\n"); |
2914 | LOG (llevError, "BUG: apply_special(): applied skill is not a chosen skill\n"); |
2915 | } |
2915 | } |
2916 | if (who->type == PLAYER) |
2916 | if (who->type == PLAYER) |
2917 | { |
2917 | { |
2918 | if (who->contr->shoottype == range_skill) |
2918 | if (who->contr->shoottype == range_skill) |
2919 | who->contr->shoottype = range_none; |
|
|
2920 | if (!op->invisible) |
|
|
2921 | { |
|
|
2922 | new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op)); |
|
|
2923 | } |
|
|
2924 | else |
|
|
2925 | { |
|
|
2926 | new_draw_info_format (NDI_UNIQUE, 0, who, "You can no longer use the skill: %s.", &op->skill); |
|
|
2927 | } |
|
|
2928 | } |
|
|
2929 | (void) change_abil (who, op); |
|
|
2930 | who->chosen_skill = NULL; |
|
|
2931 | CLEAR_FLAG (who, FLAG_READY_SKILL); |
|
|
2932 | break; |
|
|
2933 | |
|
|
2934 | case ARMOUR: |
|
|
2935 | case HELMET: |
|
|
2936 | case SHIELD: |
|
|
2937 | case RING: |
|
|
2938 | case BOOTS: |
|
|
2939 | case GLOVES: |
|
|
2940 | case AMULET: |
|
|
2941 | case GIRDLE: |
|
|
2942 | case BRACERS: |
|
|
2943 | case CLOAK: |
|
|
2944 | new_draw_info_format (NDI_UNIQUE, 0, who, "You unwear %s.", query_name (op)); |
|
|
2945 | (void) change_abil (who, op); |
|
|
2946 | break; |
|
|
2947 | case LAMP: |
|
|
2948 | new_draw_info_format (NDI_UNIQUE, 0, who, "You turn off your %s.", &op->name); |
|
|
2949 | tmp2 = arch_to_object (op->other_arch); |
|
|
2950 | tmp2->x = op->x; |
|
|
2951 | tmp2->y = op->y; |
|
|
2952 | tmp2->map = op->map; |
|
|
2953 | tmp2->below = op->below; |
|
|
2954 | tmp2->above = op->above; |
|
|
2955 | tmp2->stats.food = op->stats.food; |
|
|
2956 | CLEAR_FLAG (tmp2, FLAG_APPLIED); |
|
|
2957 | if (QUERY_FLAG (op, FLAG_INV_LOCKED)) |
|
|
2958 | SET_FLAG (tmp2, FLAG_INV_LOCKED); |
|
|
2959 | if (who->type == PLAYER) |
|
|
2960 | esrv_del_item (who->contr, (tag_t) op->count); |
|
|
2961 | remove_ob (op); |
|
|
2962 | free_object (op); |
|
|
2963 | insert_ob_in_ob (tmp2, who); |
|
|
2964 | fix_player (who); |
|
|
2965 | if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) |
|
|
2966 | { |
|
|
2967 | if (who->type == PLAYER) |
|
|
2968 | { |
|
|
2969 | new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); |
|
|
2970 | SET_FLAG (tmp2, FLAG_KNOWN_CURSED); |
|
|
2971 | } |
|
|
2972 | } |
|
|
2973 | if (who->type == PLAYER) |
|
|
2974 | esrv_send_item (who, tmp2); |
|
|
2975 | return 1; /* otherwise, an attempt to drop causes problems */ |
|
|
2976 | break; |
|
|
2977 | case BOW: |
|
|
2978 | case WAND: |
|
|
2979 | case ROD: |
|
|
2980 | case HORN: |
|
|
2981 | clear_skill (who); |
|
|
2982 | new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op)); |
|
|
2983 | if (who->type == PLAYER) |
|
|
2984 | { |
|
|
2985 | who->contr->shoottype = range_none; |
2919 | who->contr->shoottype = range_none; |
2986 | } |
2920 | if (!op->invisible) |
2987 | else |
|
|
2988 | { |
2921 | { |
2989 | if (op->type == BOW) |
2922 | new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op)); |
2990 | CLEAR_FLAG (who, FLAG_READY_BOW); |
2923 | } |
2991 | else |
2924 | else |
2992 | CLEAR_FLAG (who, FLAG_READY_RANGE); |
2925 | { |
|
|
2926 | new_draw_info_format (NDI_UNIQUE, 0, who, "You can no longer use the skill: %s.", &op->skill); |
2993 | } |
2927 | } |
|
|
2928 | } |
|
|
2929 | (void) change_abil (who, op); |
|
|
2930 | who->chosen_skill = NULL; |
|
|
2931 | CLEAR_FLAG (who, FLAG_READY_SKILL); |
2994 | break; |
2932 | break; |
2995 | |
2933 | |
|
|
2934 | case ARMOUR: |
|
|
2935 | case HELMET: |
2996 | case BUILDER: |
2936 | case SHIELD: |
|
|
2937 | case RING: |
|
|
2938 | case BOOTS: |
|
|
2939 | case GLOVES: |
|
|
2940 | case AMULET: |
|
|
2941 | case GIRDLE: |
|
|
2942 | case BRACERS: |
|
|
2943 | case CLOAK: |
|
|
2944 | new_draw_info_format (NDI_UNIQUE, 0, who, "You unwear %s.", query_name (op)); |
|
|
2945 | (void) change_abil (who, op); |
|
|
2946 | break; |
|
|
2947 | case LAMP: |
|
|
2948 | new_draw_info_format (NDI_UNIQUE, 0, who, "You turn off your %s.", &op->name); |
|
|
2949 | tmp2 = arch_to_object (op->other_arch); |
|
|
2950 | tmp2->x = op->x; |
|
|
2951 | tmp2->y = op->y; |
|
|
2952 | tmp2->map = op->map; |
|
|
2953 | tmp2->below = op->below; |
|
|
2954 | tmp2->above = op->above; |
|
|
2955 | tmp2->stats.food = op->stats.food; |
|
|
2956 | CLEAR_FLAG (tmp2, FLAG_APPLIED); |
|
|
2957 | if (QUERY_FLAG (op, FLAG_INV_LOCKED)) |
|
|
2958 | SET_FLAG (tmp2, FLAG_INV_LOCKED); |
|
|
2959 | if (who->type == PLAYER) |
|
|
2960 | esrv_del_item (who->contr, (tag_t) op->count); |
|
|
2961 | remove_ob (op); |
|
|
2962 | free_object (op); |
|
|
2963 | insert_ob_in_ob (tmp2, who); |
|
|
2964 | fix_player (who); |
|
|
2965 | if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) |
|
|
2966 | { |
|
|
2967 | if (who->type == PLAYER) |
|
|
2968 | { |
|
|
2969 | new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); |
|
|
2970 | SET_FLAG (tmp2, FLAG_KNOWN_CURSED); |
|
|
2971 | } |
|
|
2972 | } |
|
|
2973 | if (who->type == PLAYER) |
|
|
2974 | esrv_send_item (who, tmp2); |
|
|
2975 | return 1; /* otherwise, an attempt to drop causes problems */ |
|
|
2976 | break; |
|
|
2977 | case BOW: |
|
|
2978 | case WAND: |
|
|
2979 | case ROD: |
|
|
2980 | case HORN: |
|
|
2981 | clear_skill (who); |
2997 | new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op)); |
2982 | new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op)); |
|
|
2983 | if (who->type == PLAYER) |
|
|
2984 | { |
2998 | who->contr->shoottype = range_none; |
2985 | who->contr->shoottype = range_none; |
|
|
2986 | } |
|
|
2987 | else |
|
|
2988 | { |
|
|
2989 | if (op->type == BOW) |
|
|
2990 | CLEAR_FLAG (who, FLAG_READY_BOW); |
|
|
2991 | else |
|
|
2992 | CLEAR_FLAG (who, FLAG_READY_RANGE); |
|
|
2993 | } |
|
|
2994 | break; |
|
|
2995 | |
|
|
2996 | case BUILDER: |
|
|
2997 | new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op)); |
|
|
2998 | who->contr->shoottype = range_none; |
2999 | who->contr->ranges[range_builder] = NULL; |
2999 | who->contr->ranges[range_builder] = NULL; |
3000 | break; |
3000 | break; |
3001 | |
3001 | |
3002 | default: |
3002 | default: |
3003 | new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op)); |
3003 | new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op)); |
3004 | break; |
3004 | break; |
3005 | } |
3005 | } |
3006 | |
3006 | |
3007 | fix_player (who); |
3007 | fix_player (who); |
3008 | |
3008 | |
3009 | if (!(aflags & AP_NO_MERGE)) |
3009 | if (!(aflags & AP_NO_MERGE)) |
… | |
… | |
3431 | if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op))) |
3431 | if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op))) |
3432 | return RESULT_INT (0); |
3432 | return RESULT_INT (0); |
3433 | |
3433 | |
3434 | switch (op->type) |
3434 | switch (op->type) |
3435 | { |
3435 | { |
3436 | case WEAPON: |
3436 | case WEAPON: |
3437 | if (!check_weapon_power (who, op->last_eat)) |
3437 | if (!check_weapon_power (who, op->last_eat)) |
3438 | { |
3438 | { |
3439 | new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use."); |
3439 | new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use."); |
3440 | new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); |
3440 | new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); |
3441 | if (tmp != NULL) |
3441 | if (tmp != NULL) |
3442 | (void) insert_ob_in_ob (tmp, who); |
|
|
3443 | return 1; |
|
|
3444 | } |
|
|
3445 | if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) |
|
|
3446 | { |
|
|
3447 | /* if the weapon does not have the name as the character, can't use it. */ |
|
|
3448 | /* (Ragnarok's sword attempted to be used by Foo: won't work) */ |
|
|
3449 | new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); |
|
|
3450 | if (tmp != NULL) |
|
|
3451 | (void) insert_ob_in_ob (tmp, who); |
|
|
3452 | return 1; |
|
|
3453 | } |
|
|
3454 | SET_FLAG (op, FLAG_APPLIED); |
|
|
3455 | |
|
|
3456 | if (skop) |
|
|
3457 | change_skill (who, skop, 1); |
|
|
3458 | if (!QUERY_FLAG (who, FLAG_READY_WEAPON)) |
|
|
3459 | SET_FLAG (who, FLAG_READY_WEAPON); |
|
|
3460 | |
|
|
3461 | new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op)); |
|
|
3462 | |
|
|
3463 | (void) change_abil (who, op); |
|
|
3464 | break; |
|
|
3465 | |
|
|
3466 | case ARMOUR: |
|
|
3467 | case HELMET: |
|
|
3468 | case SHIELD: |
|
|
3469 | case BOOTS: |
|
|
3470 | case GLOVES: |
|
|
3471 | case GIRDLE: |
|
|
3472 | case BRACERS: |
|
|
3473 | case CLOAK: |
|
|
3474 | case RING: |
|
|
3475 | case AMULET: |
|
|
3476 | SET_FLAG (op, FLAG_APPLIED); |
|
|
3477 | new_draw_info_format (NDI_UNIQUE, 0, who, "You wear %s.", query_name (op)); |
|
|
3478 | (void) change_abil (who, op); |
|
|
3479 | break; |
|
|
3480 | case LAMP: |
|
|
3481 | if (op->stats.food < 1) |
|
|
3482 | { |
|
|
3483 | new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name); |
|
|
3484 | return 1; |
|
|
3485 | } |
|
|
3486 | new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name); |
|
|
3487 | tmp2 = arch_to_object (op->other_arch); |
|
|
3488 | tmp2->stats.food = op->stats.food; |
|
|
3489 | SET_FLAG (tmp2, FLAG_APPLIED); |
|
|
3490 | if (QUERY_FLAG (op, FLAG_INV_LOCKED)) |
|
|
3491 | SET_FLAG (tmp2, FLAG_INV_LOCKED); |
|
|
3492 | insert_ob_in_ob (tmp2, who); |
|
|
3493 | |
|
|
3494 | /* Remove the old lantern */ |
|
|
3495 | if (who->type == PLAYER) |
|
|
3496 | esrv_del_item (who->contr, (tag_t) op->count); |
|
|
3497 | remove_ob (op); |
|
|
3498 | free_object (op); |
|
|
3499 | |
|
|
3500 | /* insert the portion that was split off */ |
|
|
3501 | if (tmp != NULL) |
|
|
3502 | { |
|
|
3503 | (void) insert_ob_in_ob (tmp, who); |
3442 | (void) insert_ob_in_ob (tmp, who); |
|
|
3443 | return 1; |
|
|
3444 | } |
|
|
3445 | if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) |
|
|
3446 | { |
|
|
3447 | /* if the weapon does not have the name as the character, can't use it. */ |
|
|
3448 | /* (Ragnarok's sword attempted to be used by Foo: won't work) */ |
|
|
3449 | new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); |
|
|
3450 | if (tmp != NULL) |
|
|
3451 | (void) insert_ob_in_ob (tmp, who); |
|
|
3452 | return 1; |
|
|
3453 | } |
|
|
3454 | SET_FLAG (op, FLAG_APPLIED); |
|
|
3455 | |
|
|
3456 | if (skop) |
|
|
3457 | change_skill (who, skop, 1); |
|
|
3458 | if (!QUERY_FLAG (who, FLAG_READY_WEAPON)) |
|
|
3459 | SET_FLAG (who, FLAG_READY_WEAPON); |
|
|
3460 | |
|
|
3461 | new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op)); |
|
|
3462 | |
|
|
3463 | (void) change_abil (who, op); |
|
|
3464 | break; |
|
|
3465 | |
|
|
3466 | case ARMOUR: |
|
|
3467 | case HELMET: |
|
|
3468 | case SHIELD: |
|
|
3469 | case BOOTS: |
|
|
3470 | case GLOVES: |
|
|
3471 | case GIRDLE: |
|
|
3472 | case BRACERS: |
|
|
3473 | case CLOAK: |
|
|
3474 | case RING: |
|
|
3475 | case AMULET: |
|
|
3476 | SET_FLAG (op, FLAG_APPLIED); |
|
|
3477 | new_draw_info_format (NDI_UNIQUE, 0, who, "You wear %s.", query_name (op)); |
|
|
3478 | (void) change_abil (who, op); |
|
|
3479 | break; |
|
|
3480 | case LAMP: |
|
|
3481 | if (op->stats.food < 1) |
|
|
3482 | { |
|
|
3483 | new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name); |
|
|
3484 | return 1; |
|
|
3485 | } |
|
|
3486 | new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name); |
|
|
3487 | tmp2 = arch_to_object (op->other_arch); |
|
|
3488 | tmp2->stats.food = op->stats.food; |
|
|
3489 | SET_FLAG (tmp2, FLAG_APPLIED); |
|
|
3490 | if (QUERY_FLAG (op, FLAG_INV_LOCKED)) |
|
|
3491 | SET_FLAG (tmp2, FLAG_INV_LOCKED); |
|
|
3492 | insert_ob_in_ob (tmp2, who); |
|
|
3493 | |
|
|
3494 | /* Remove the old lantern */ |
|
|
3495 | if (who->type == PLAYER) |
|
|
3496 | esrv_del_item (who->contr, (tag_t) op->count); |
|
|
3497 | remove_ob (op); |
|
|
3498 | free_object (op); |
|
|
3499 | |
|
|
3500 | /* insert the portion that was split off */ |
|
|
3501 | if (tmp != NULL) |
|
|
3502 | { |
|
|
3503 | (void) insert_ob_in_ob (tmp, who); |
3504 | if (who->type == PLAYER) |
3504 | if (who->type == PLAYER) |
3505 | esrv_send_item (who, tmp); |
3505 | esrv_send_item (who, tmp); |
3506 | } |
3506 | } |
3507 | fix_player (who); |
3507 | fix_player (who); |
3508 | if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) |
3508 | if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) |
3509 | { |
3509 | { |
3510 | if (who->type == PLAYER) |
3510 | if (who->type == PLAYER) |
3511 | { |
3511 | { |
3512 | new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); |
3512 | new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); |
3513 | SET_FLAG (tmp2, FLAG_KNOWN_CURSED); |
3513 | SET_FLAG (tmp2, FLAG_KNOWN_CURSED); |
3514 | } |
3514 | } |
3515 | } |
3515 | } |
3516 | if (who->type == PLAYER) |
3516 | if (who->type == PLAYER) |
3517 | esrv_send_item (who, tmp2); |
3517 | esrv_send_item (who, tmp2); |
3518 | return 0; |
3518 | return 0; |
3519 | break; |
3519 | break; |
3520 | |
3520 | |
3521 | /* this part is needed for skill-tools */ |
3521 | /* this part is needed for skill-tools */ |
3522 | case SKILL: |
3522 | case SKILL: |
3523 | case SKILL_TOOL: |
3523 | case SKILL_TOOL: |
3524 | if (who->chosen_skill) |
3524 | if (who->chosen_skill) |
3525 | { |
3525 | { |
3526 | LOG (llevError, "BUG: apply_special(): can't apply two skills\n"); |
3526 | LOG (llevError, "BUG: apply_special(): can't apply two skills\n"); |
3527 | return 1; |
3527 | return 1; |
3528 | } |
3528 | } |
3529 | if (who->type == PLAYER) |
3529 | if (who->type == PLAYER) |
3530 | { |
3530 | { |
3531 | who->contr->shoottype = range_skill; |
3531 | who->contr->shoottype = range_skill; |
3532 | who->contr->ranges[range_skill] = op; |
3532 | who->contr->ranges[range_skill] = op; |
3533 | if (!op->invisible) |
3533 | if (!op->invisible) |
3534 | { |
3534 | { |
3535 | new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); |
3535 | new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); |
3536 | new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill); |
3536 | new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill); |
3537 | } |
3537 | } |
3538 | else |
3538 | else |
3539 | { |
3539 | { |
3540 | new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name); |
3540 | new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name); |
3541 | } |
3541 | } |
3542 | } |
3542 | } |
3543 | SET_FLAG (op, FLAG_APPLIED); |
3543 | SET_FLAG (op, FLAG_APPLIED); |
3544 | (void) change_abil (who, op); |
3544 | (void) change_abil (who, op); |
3545 | who->chosen_skill = op; |
3545 | who->chosen_skill = op; |
3546 | SET_FLAG (who, FLAG_READY_SKILL); |
3546 | SET_FLAG (who, FLAG_READY_SKILL); |
3547 | break; |
3547 | break; |
3548 | |
3548 | |
3549 | case BOW: |
3549 | case BOW: |
3550 | if (!check_weapon_power (who, op->last_eat)) |
3550 | if (!check_weapon_power (who, op->last_eat)) |
3551 | { |
3551 | { |
3552 | new_draw_info (NDI_UNIQUE, 0, who, "That item is too powerful for you to use."); |
3552 | new_draw_info (NDI_UNIQUE, 0, who, "That item is too powerful for you to use."); |
3553 | new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); |
3553 | new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); |
3554 | if (tmp != NULL) |
3554 | if (tmp != NULL) |
3555 | (void) insert_ob_in_ob (tmp, who); |
3555 | (void) insert_ob_in_ob (tmp, who); |
3556 | return 1; |
3556 | return 1; |
3557 | } |
3557 | } |
3558 | if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) |
3558 | if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) |
3559 | { |
3559 | { |
3560 | new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); |
3560 | new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); |
3561 | if (tmp != NULL) |
3561 | if (tmp != NULL) |
3562 | (void) insert_ob_in_ob (tmp, who); |
3562 | (void) insert_ob_in_ob (tmp, who); |
3563 | return 1; |
3563 | return 1; |
3564 | } |
3564 | } |
3565 | /*FALLTHROUGH*/ case WAND: |
3565 | /*FALLTHROUGH*/ case WAND: |
3566 | case ROD: |
3566 | case ROD: |
3567 | case HORN: |
3567 | case HORN: |
3568 | /* check for skill, alter player status */ |
3568 | /* check for skill, alter player status */ |
3569 | SET_FLAG (op, FLAG_APPLIED); |
3569 | SET_FLAG (op, FLAG_APPLIED); |
3570 | if (skop) |
3570 | if (skop) |
3571 | change_skill (who, skop, 0); |
3571 | change_skill (who, skop, 0); |
3572 | new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); |
3572 | new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); |
3573 | |
3573 | |
3574 | if (who->type == PLAYER) |
3574 | if (who->type == PLAYER) |
3575 | { |
3575 | { |
3576 | if (op->type == BOW) |
3576 | if (op->type == BOW) |
3577 | { |
3577 | { |
3578 | (void) change_abil (who, op); |
3578 | (void) change_abil (who, op); |
3579 | new_draw_info_format (NDI_UNIQUE, 0, who, |
3579 | new_draw_info_format (NDI_UNIQUE, 0, who, |
3580 | "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op)); |
3580 | "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op)); |
3581 | who->contr->shoottype = range_bow; |
3581 | who->contr->shoottype = range_bow; |
3582 | } |
3582 | } |
3583 | else |
3583 | else |
3584 | { |
3584 | { |
3585 | who->contr->shoottype = range_misc; |
3585 | who->contr->shoottype = range_misc; |
3586 | } |
3586 | } |
3587 | } |
3587 | } |
3588 | else |
3588 | else |
3589 | { |
3589 | { |
3590 | if (op->type == BOW) |
3590 | if (op->type == BOW) |
3591 | SET_FLAG (who, FLAG_READY_BOW); |
3591 | SET_FLAG (who, FLAG_READY_BOW); |
3592 | else |
3592 | else |
3593 | SET_FLAG (who, FLAG_READY_RANGE); |
3593 | SET_FLAG (who, FLAG_READY_RANGE); |
3594 | } |
3594 | } |
3595 | break; |
3595 | break; |
3596 | |
3596 | |
3597 | case BUILDER: |
3597 | case BUILDER: |
3598 | if (who->contr->ranges[range_builder]) |
3598 | if (who->contr->ranges[range_builder]) |
3599 | unapply_special (who, who->contr->ranges[range_builder], 0); |
3599 | unapply_special (who, who->contr->ranges[range_builder], 0); |
3600 | who->contr->shoottype = range_builder; |
3600 | who->contr->shoottype = range_builder; |
3601 | who->contr->ranges[range_builder] = op; |
3601 | who->contr->ranges[range_builder] = op; |
3602 | new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op)); |
3602 | new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op)); |
3603 | break; |
3603 | break; |
3604 | |
3604 | |
3605 | default: |
3605 | default: |
3606 | new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op)); |
3606 | new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op)); |
3607 | } /* end of switch op->type */ |
3607 | } /* end of switch op->type */ |
3608 | |
3608 | |
3609 | SET_FLAG (op, FLAG_APPLIED); |
3609 | SET_FLAG (op, FLAG_APPLIED); |
3610 | |
3610 | |
3611 | if (tmp != NULL) |
3611 | if (tmp != NULL) |
… | |
… | |
3658 | object *tmp = NULL, *tmp2; |
3658 | object *tmp = NULL, *tmp2; |
3659 | int i; |
3659 | int i; |
3660 | |
3660 | |
3661 | switch (op->type) |
3661 | switch (op->type) |
3662 | { |
3662 | { |
3663 | case SHOP_FLOOR: |
3663 | case SHOP_FLOOR: |
3664 | if (!HAS_RANDOM_ITEMS (op)) |
3664 | if (!HAS_RANDOM_ITEMS (op)) |
3665 | return 0; |
3665 | return 0; |
3666 | do |
3666 | do |
3667 | { |
3667 | { |
3668 | i = 10; /* let's give it 10 tries */ |
3668 | i = 10; /* let's give it 10 tries */ |
3669 | while ((tmp = generate_treasure (op->randomitems, |
3669 | while ((tmp = generate_treasure (op->randomitems, |
3670 | op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i); |
3670 | op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i); |
3671 | if (tmp == NULL) |
3671 | if (tmp == NULL) |
3672 | return 0; |
3672 | return 0; |
3673 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
3673 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
3674 | { |
3674 | { |
3675 | free_object (tmp); |
|
|
3676 | tmp = NULL; |
|
|
3677 | } |
|
|
3678 | } |
|
|
3679 | while (!tmp); |
|
|
3680 | tmp->x = op->x; |
|
|
3681 | tmp->y = op->y; |
|
|
3682 | SET_FLAG (tmp, FLAG_UNPAID); |
|
|
3683 | insert_ob_in_map (tmp, op->map, NULL, 0); |
|
|
3684 | CLEAR_FLAG (op, FLAG_AUTO_APPLY); |
|
|
3685 | identify (tmp); |
|
|
3686 | break; |
|
|
3687 | |
|
|
3688 | case TREASURE: |
|
|
3689 | if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) |
|
|
3690 | return 0; |
|
|
3691 | while ((op->stats.hp--) > 0) |
|
|
3692 | create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0, |
|
|
3693 | op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0); |
|
|
3694 | |
|
|
3695 | /* If we generated an object and put it in this object inventory, |
|
|
3696 | * move it to the parent object as the current object is about |
|
|
3697 | * to disappear. An example of this item is the random_* stuff |
|
|
3698 | * that is put inside other objects. |
|
|
3699 | */ |
|
|
3700 | for (tmp = op->inv; tmp; tmp = tmp2) |
|
|
3701 | { |
|
|
3702 | tmp2 = tmp->below; |
|
|
3703 | remove_ob (tmp); |
|
|
3704 | if (op->env) |
|
|
3705 | insert_ob_in_ob (tmp, op->env); |
|
|
3706 | else |
|
|
3707 | free_object (tmp); |
3675 | free_object (tmp); |
|
|
3676 | tmp = NULL; |
3708 | } |
3677 | } |
|
|
3678 | } |
|
|
3679 | while (!tmp); |
|
|
3680 | tmp->x = op->x; |
|
|
3681 | tmp->y = op->y; |
|
|
3682 | SET_FLAG (tmp, FLAG_UNPAID); |
|
|
3683 | insert_ob_in_map (tmp, op->map, NULL, 0); |
|
|
3684 | CLEAR_FLAG (op, FLAG_AUTO_APPLY); |
|
|
3685 | identify (tmp); |
|
|
3686 | break; |
|
|
3687 | |
|
|
3688 | case TREASURE: |
|
|
3689 | if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) |
|
|
3690 | return 0; |
|
|
3691 | while ((op->stats.hp--) > 0) |
|
|
3692 | create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0, |
|
|
3693 | op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0); |
|
|
3694 | |
|
|
3695 | /* If we generated an object and put it in this object inventory, |
|
|
3696 | * move it to the parent object as the current object is about |
|
|
3697 | * to disappear. An example of this item is the random_* stuff |
|
|
3698 | * that is put inside other objects. |
|
|
3699 | */ |
|
|
3700 | for (tmp = op->inv; tmp; tmp = tmp2) |
|
|
3701 | { |
|
|
3702 | tmp2 = tmp->below; |
|
|
3703 | remove_ob (tmp); |
|
|
3704 | if (op->env) |
|
|
3705 | insert_ob_in_ob (tmp, op->env); |
|
|
3706 | else |
|
|
3707 | free_object (tmp); |
|
|
3708 | } |
3709 | remove_ob (op); |
3709 | remove_ob (op); |
3710 | free_object (op); |
3710 | free_object (op); |
3711 | break; |
3711 | break; |
3712 | } |
3712 | } |
3713 | return tmp ? 1 : 0; |
3713 | return tmp ? 1 : 0; |
3714 | } |
3714 | } |
3715 | |
3715 | |
3716 | /** |
3716 | /** |
… | |
… | |
4052 | for the race, put the excess stat some |
4052 | for the race, put the excess stat some |
4053 | where else. */ |
4053 | where else. */ |
4054 | |
4054 | |
4055 | switch (change->type) |
4055 | switch (change->type) |
4056 | { |
4056 | { |
4057 | case CLASS: |
4057 | case CLASS: |
4058 | { |
4058 | { |
4059 | living *stats = &(pl->contr->orig_stats); |
4059 | living *stats = &(pl->contr->orig_stats); |
4060 | living *ns = &(change->stats); |
4060 | living *ns = &(change->stats); |
4061 | object *walk; |
4061 | object *walk; |
4062 | int flag_change_face = 1; |
4062 | int flag_change_face = 1; |
4063 | |
4063 | |
4064 | /* the following code assigns stats up to the stat max |
4064 | /* the following code assigns stats up to the stat max |
4065 | * for the race, and if the stat max is exceeded, |
4065 | * for the race, and if the stat max is exceeded, |
4066 | * tries to randomly reassign the excess stat |
4066 | * tries to randomly reassign the excess stat |
4067 | */ |
4067 | */ |
4068 | int i, j; |
4068 | int i, j; |
4069 | |
4069 | |
4070 | for (i = 0; i < NUM_STATS; i++) |
4070 | for (i = 0; i < NUM_STATS; i++) |
4071 | { |
4071 | { |
4072 | sint8 stat = get_attr_value (stats, i); |
4072 | sint8 stat = get_attr_value (stats, i); |
4073 | int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); |
4073 | int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); |
4074 | |
4074 | |
4075 | stat += get_attr_value (ns, i); |
4075 | stat += get_attr_value (ns, i); |
4076 | if (stat > 20 + race_bonus) |
4076 | if (stat > 20 + race_bonus) |
4077 | { |
4077 | { |
4078 | excess_stat++; |
4078 | excess_stat++; |
4079 | stat = 20 + race_bonus; |
4079 | stat = 20 + race_bonus; |
4080 | } |
4080 | } |
4081 | set_attr_value (stats, i, stat); |
4081 | set_attr_value (stats, i, stat); |
4082 | } |
4082 | } |
4083 | |
4083 | |
4084 | for (j = 0; excess_stat > 0 && j < 100; j++) |
4084 | for (j = 0; excess_stat > 0 && j < 100; j++) |
4085 | { /* try 100 times to assign excess stats */ |
4085 | { /* try 100 times to assign excess stats */ |
4086 | int i = rndm (0, 6); |
4086 | int i = rndm (0, 6); |
4087 | int stat = get_attr_value (stats, i); |
4087 | int stat = get_attr_value (stats, i); |
4088 | int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); |
4088 | int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); |
4089 | |
4089 | |
4090 | if (i == CHA) |
4090 | if (i == CHA) |
4091 | continue; /* exclude cha from this */ |
4091 | continue; /* exclude cha from this */ |
4092 | if (stat < 20 + race_bonus) |
4092 | if (stat < 20 + race_bonus) |
4093 | { |
4093 | { |
4094 | change_attr_value (stats, i, 1); |
4094 | change_attr_value (stats, i, 1); |
4095 | excess_stat--; |
4095 | excess_stat--; |
4096 | } |
4096 | } |
4097 | } |
4097 | } |
4098 | |
4098 | |
4099 | /* insert the randomitems from the change's treasurelist into |
4099 | /* insert the randomitems from the change's treasurelist into |
4100 | * the player ref: player.c |
4100 | * the player ref: player.c |
4101 | */ |
4101 | */ |
4102 | if (change->randomitems != NULL) |
4102 | if (change->randomitems != NULL) |
4103 | give_initial_items (pl, change->randomitems); |
4103 | give_initial_items (pl, change->randomitems); |
4104 | |
4104 | |
4105 | |
4105 | |
4106 | /* set up the face, for some races. */ |
4106 | /* set up the face, for some races. */ |
4107 | |
4107 | |
4108 | /* first, look for the force object banning |
4108 | /* first, look for the force object banning |
4109 | * changing the face. Certain races never change face with class. |
4109 | * changing the face. Certain races never change face with class. |
4110 | */ |
4110 | */ |
4111 | for (walk = pl->inv; walk != NULL; walk = walk->below) |
4111 | for (walk = pl->inv; walk != NULL; walk = walk->below) |
4112 | if (!strcmp (walk->name, "NOCLASSFACECHANGE")) |
4112 | if (!strcmp (walk->name, "NOCLASSFACECHANGE")) |
4113 | flag_change_face = 0; |
4113 | flag_change_face = 0; |
4114 | |
4114 | |
4115 | if (flag_change_face) |
4115 | if (flag_change_face) |
4116 | { |
4116 | { |
4117 | pl->animation_id = GET_ANIM_ID (change); |
4117 | pl->animation_id = GET_ANIM_ID (change); |
4118 | pl->face = change->face; |
4118 | pl->face = change->face; |
4119 | |
4119 | |
4120 | if (QUERY_FLAG (change, FLAG_ANIMATE)) |
4120 | if (QUERY_FLAG (change, FLAG_ANIMATE)) |
4121 | SET_FLAG (pl, FLAG_ANIMATE); |
4121 | SET_FLAG (pl, FLAG_ANIMATE); |
4122 | else |
4122 | else |
4123 | CLEAR_FLAG (pl, FLAG_ANIMATE); |
4123 | CLEAR_FLAG (pl, FLAG_ANIMATE); |
4124 | } |
4124 | } |
4125 | |
4125 | |
4126 | /* check the special case of can't use weapons */ |
4126 | /* check the special case of can't use weapons */ |
4127 | /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */ |
4127 | /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */ |
4128 | if (!strcmp (change->name, "monk")) |
4128 | if (!strcmp (change->name, "monk")) |
4129 | CLEAR_FLAG (pl, FLAG_USE_WEAPON); |
4129 | CLEAR_FLAG (pl, FLAG_USE_WEAPON); |
4130 | |
4130 | |
4131 | break; |
4131 | break; |
4132 | } |
4132 | } |
4133 | } |
4133 | } |
4134 | } |
4134 | } |
4135 | |
4135 | |
4136 | /** |
4136 | /** |
4137 | * This handles items of type 'transformer'. |
4137 | * This handles items of type 'transformer'. |