… | |
… | |
2820 | return tmp; |
2820 | return tmp; |
2821 | |
2821 | |
2822 | return NULL; |
2822 | return NULL; |
2823 | } |
2823 | } |
2824 | |
2824 | |
2825 | |
|
|
2826 | |
|
|
2827 | /** |
2825 | /** |
2828 | * 'op' wants to apply an object, but can't because of other equipment. |
2826 | * 'op' wants to apply an object, but can't because of other equipment. |
2829 | * This should only be called when it is known |
2827 | * This should only be called when it is known |
2830 | * that there are objects to unapply. This makes pretty heavy |
2828 | * that there are objects to unapply. This makes pretty heavy |
2831 | * use of get_item_from_body_location. It makes no intelligent choice |
2829 | * use of get_item_from_body_location. It makes no intelligent choice |
… | |
… | |
2836 | * another function that does just that. |
2834 | * another function that does just that. |
2837 | */ |
2835 | */ |
2838 | int |
2836 | int |
2839 | unapply_for_ob (object *who, object *op, int aflags) |
2837 | unapply_for_ob (object *who, object *op, int aflags) |
2840 | { |
2838 | { |
2841 | int i; |
|
|
2842 | object *tmp = NULL, *last; |
|
|
2843 | |
|
|
2844 | /* If we are applying a shield or weapon, unapply any equipped shield |
2839 | /* If we are applying a shield or weapon, unapply any equipped shield |
2845 | * or weapons first - only allowed to use one weapon/shield at a time. |
2840 | * or weapons first - only allowed to use one weapon/shield at a time. |
2846 | */ |
2841 | */ |
2847 | if (op->type == WEAPON || op->type == SHIELD) |
2842 | if (op->type == WEAPON || op->type == SHIELD) |
2848 | { |
|
|
2849 | for (tmp = who->inv; tmp; tmp = tmp->below) |
2843 | for (object *tmp = who->inv; tmp; tmp = tmp->below) |
2850 | { |
|
|
2851 | if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == op->type) |
2844 | if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == op->type) |
2852 | { |
|
|
2853 | if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED))) |
2845 | if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED))) |
2854 | { |
2846 | { |
2855 | if (aflags & AP_PRINT) |
2847 | if (aflags & AP_PRINT) |
2856 | new_draw_info (NDI_UNIQUE, 0, who, query_name (tmp)); |
2848 | new_draw_info (NDI_UNIQUE, 0, who, query_name (tmp)); |
2857 | else |
2849 | else |
2858 | unapply_special (who, tmp, aflags); |
2850 | unapply_special (who, tmp, aflags); |
2859 | } |
2851 | } |
2860 | else |
2852 | else |
2861 | { |
2853 | { |
2862 | /* In this case, we want to try and remove a cursed item. |
2854 | /* In this case, we want to try and remove a cursed item. |
2863 | * While we know it won't work, we want unapply_special to |
2855 | * While we know it won't work, we want unapply_special to |
2864 | * at least generate the message. |
2856 | * at least generate the message. |
2865 | */ |
2857 | */ |
2866 | new_draw_info_format (NDI_UNIQUE, 0, who, "No matter how hard you try, you just can't\nremove %s.", query_name (tmp)); |
2858 | new_draw_info_format (NDI_UNIQUE, 0, who, "No matter how hard you try, you just can't remove the %s.", query_name (tmp)); |
2867 | return 1; |
2859 | return 1; |
2868 | } |
|
|
2869 | |
|
|
2870 | } |
2860 | } |
|
|
2861 | |
|
|
2862 | if (op->is_range ()) |
|
|
2863 | for (object *tmp = who->inv; tmp; tmp = tmp->below) |
|
|
2864 | if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->is_range ()) |
|
|
2865 | if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED))) |
|
|
2866 | { |
|
|
2867 | if (aflags & AP_PRINT) |
|
|
2868 | new_draw_info (NDI_UNIQUE, 0, who, query_name (tmp)); |
|
|
2869 | else |
|
|
2870 | unapply_special (who, tmp, aflags); |
2871 | } |
2871 | } |
2872 | } |
2872 | else |
|
|
2873 | { |
|
|
2874 | /* In this case, we want to try and remove a cursed item. |
|
|
2875 | * While we know it won't work, we want unapply_special to |
|
|
2876 | * at least generate the message. |
|
|
2877 | */ |
|
|
2878 | new_draw_info_format (NDI_UNIQUE, 0, who, "No matter how hard you try, you just can't remove the %s.", query_name (tmp)); |
|
|
2879 | return 1; |
|
|
2880 | } |
2873 | |
2881 | |
2874 | for (i = 0; i < NUM_BODY_LOCATIONS; i++) |
2882 | for (int i = 0; i < NUM_BODY_LOCATIONS; i++) |
2875 | { |
2883 | { |
2876 | /* this used up a slot that we need to free */ |
2884 | /* this used up a slot that we need to free */ |
2877 | if (op->body_info[i]) |
2885 | if (op->body_info[i]) |
2878 | { |
2886 | { |
2879 | last = who->inv; |
2887 | object *last = who->inv; |
2880 | |
2888 | |
2881 | /* We do a while loop - may need to remove several items in order |
2889 | /* We do a while loop - may need to remove several items in order |
2882 | * to free up enough slots. |
2890 | * to free up enough slots. |
2883 | */ |
2891 | */ |
2884 | while ((who->body_used[i] + op->body_info[i]) < 0) |
2892 | while ((who->body_used[i] + op->body_info[i]) < 0) |
2885 | { |
2893 | { |
2886 | tmp = get_item_from_body_location (last, i); |
2894 | object *tmp = get_item_from_body_location (last, i); |
|
|
2895 | |
2887 | if (!tmp) |
2896 | if (!tmp) |
2888 | { |
2897 | { |
2889 | #if 0 |
2898 | #if 0 |
2890 | /* Not a bug - we'll get this if the player has cursed items |
2899 | /* Not a bug - we'll get this if the player has cursed items |
2891 | * equipped. |
2900 | * equipped. |
2892 | */ |
2901 | */ |
2893 | LOG (llevError, "Can't find object using location %d (%s) on %s\n", i, body_locations[i].save_name, who->name); |
2902 | LOG (llevError, "Can't find object using location %d (%s) on %s\n", i, body_locations[i].save_name, who->name); |
2894 | #endif |
2903 | #endif |
2895 | return 1; |
2904 | return 1; |
2896 | } |
2905 | } |
|
|
2906 | |
2897 | /* If we are just printing, we don't care about cursed status */ |
2907 | /* If we are just printing, we don't care about cursed status */ |
2898 | if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!(QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)))) |
2908 | if ((aflags & AP_IGNORE_CURSE) || (aflags & AP_PRINT) || (!(QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)))) |
2899 | { |
2909 | { |
2900 | if (aflags & AP_PRINT) |
2910 | if (aflags & AP_PRINT) |
2901 | new_draw_info (NDI_UNIQUE, 0, who, query_name (tmp)); |
2911 | new_draw_info (NDI_UNIQUE, 0, who, query_name (tmp)); |
… | |
… | |
2909 | * so it may not be critical (eg, putting on a ring and you have |
2919 | * so it may not be critical (eg, putting on a ring and you have |
2910 | * one cursed ring.) |
2920 | * one cursed ring.) |
2911 | */ |
2921 | */ |
2912 | new_draw_info_format (NDI_UNIQUE, 0, who, "The %s just won't come off", query_name (tmp)); |
2922 | new_draw_info_format (NDI_UNIQUE, 0, who, "The %s just won't come off", query_name (tmp)); |
2913 | } |
2923 | } |
|
|
2924 | |
2914 | last = tmp->below; |
2925 | last = tmp->below; |
2915 | } |
2926 | } |
2916 | /* if we got here, this slot is freed up - otherwise, if it wasn't freed up, the |
2927 | /* if we got here, this slot is freed up - otherwise, if it wasn't freed up, the |
2917 | * return in the !tmp would have kicked in. |
2928 | * return in the !tmp would have kicked in. |
2918 | */ |
2929 | */ |
2919 | } /* if op is using this body location */ |
2930 | } /* if op is using this body location */ |
2920 | } /* for body lcoations */ |
2931 | } /* for body lcoations */ |
|
|
2932 | |
2921 | return 0; |
2933 | return 0; |
2922 | } |
2934 | } |
2923 | |
2935 | |
2924 | /** |
2936 | /** |
2925 | * Checks to see if 'who' can apply object 'op'. |
2937 | * Checks to see if 'who' can apply object 'op'. |
… | |
… | |
2944 | /* Players have 2 'arm's, so they could in theory equip 2 shields or |
2956 | /* Players have 2 'arm's, so they could in theory equip 2 shields or |
2945 | * 2 weapons, but we don't want to let them do that. So if they are |
2957 | * 2 weapons, but we don't want to let them do that. So if they are |
2946 | * trying to equip a weapon or shield, see if they already have one |
2958 | * trying to equip a weapon or shield, see if they already have one |
2947 | * in place and store that way. |
2959 | * in place and store that way. |
2948 | */ |
2960 | */ |
2949 | if (op->type == WEAPON || op->type == BOW || op->type == SHIELD) |
2961 | if (op->type == WEAPON || op->type == SHIELD) |
2950 | { |
|
|
2951 | for (tmp = who->inv; tmp && !ws; tmp = tmp->below) |
2962 | for (tmp = who->inv; tmp && !ws; tmp = tmp->below) |
2952 | { |
|
|
2953 | if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == op->type) |
2963 | if (tmp->flag [FLAG_APPLIED] && tmp->type == op->type) |
2954 | { |
2964 | { |
2955 | retval = CAN_APPLY_UNAPPLY; |
2965 | retval = CAN_APPLY_UNAPPLY; |
2956 | ws = tmp; |
2966 | ws = tmp; |
2957 | } |
2967 | } |
|
|
2968 | |
|
|
2969 | if (op->is_range ()) |
|
|
2970 | for (tmp = who->inv; tmp && !ws; tmp = tmp->below) |
|
|
2971 | if (tmp->flag [FLAG_APPLIED] && tmp->is_range ()) |
2958 | } |
2972 | { |
2959 | } |
2973 | retval = CAN_APPLY_UNAPPLY; |
|
|
2974 | ws = tmp; |
|
|
2975 | } |
2960 | |
2976 | |
2961 | for (int i = 0; i < NUM_BODY_LOCATIONS; i++) |
2977 | for (int i = 0; i < NUM_BODY_LOCATIONS; i++) |
2962 | { |
2978 | { |
2963 | if (op->body_info[i]) |
2979 | if (op->body_info[i]) |
2964 | { |
2980 | { |
… | |
… | |
3148 | new_draw_info (NDI_UNIQUE, 0, who, "You need to unapply some of the following item(s) or change your applymode:"); |
3164 | new_draw_info (NDI_UNIQUE, 0, who, "You need to unapply some of the following item(s) or change your applymode:"); |
3149 | unapply_for_ob (who, op, AP_PRINT); |
3165 | unapply_for_ob (who, op, AP_PRINT); |
3150 | return 1; |
3166 | return 1; |
3151 | } |
3167 | } |
3152 | else if (who->contr->unapply == unapply_always || !(i & CAN_APPLY_UNAPPLY_CHOICE)) |
3168 | else if (who->contr->unapply == unapply_always || !(i & CAN_APPLY_UNAPPLY_CHOICE)) |
3153 | { |
|
|
3154 | if (unapply_for_ob (who, op, aflags)) |
3169 | if (unapply_for_ob (who, op, aflags)) |
3155 | return 1; |
3170 | return 1; |
3156 | } |
|
|
3157 | } |
3171 | } |
3158 | } |
3172 | } |
3159 | |
3173 | |
3160 | if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) |
3174 | if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) |
3161 | { |
3175 | { |
… | |
… | |
3198 | switch (op->type) |
3212 | switch (op->type) |
3199 | { |
3213 | { |
3200 | case WEAPON: |
3214 | case WEAPON: |
3201 | if (!check_weapon_power (who, op->last_eat)) |
3215 | if (!check_weapon_power (who, op->last_eat)) |
3202 | { |
3216 | { |
3203 | new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use."); |
3217 | new_draw_info (NDI_UNIQUE, 0, who, "This weapon is too powerful for you to use."); |
3204 | new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); |
3218 | new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); |
3205 | |
3219 | |
3206 | if (tmp) |
3220 | if (tmp) |
3207 | insert_ob_in_ob (tmp, who); |
3221 | insert_ob_in_ob (tmp, who); |
3208 | |
3222 | |
… | |
… | |
3293 | } |
3307 | } |
3294 | |
3308 | |
3295 | who->update_stats (); |
3309 | who->update_stats (); |
3296 | |
3310 | |
3297 | if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) |
3311 | if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) |
3298 | { |
|
|
3299 | if (who->type == PLAYER) |
3312 | if (who->type == PLAYER) |
3300 | { |
3313 | { |
3301 | new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); |
3314 | new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); |
3302 | SET_FLAG (tmp2, FLAG_KNOWN_CURSED); |
3315 | SET_FLAG (tmp2, FLAG_KNOWN_CURSED); |
3303 | } |
3316 | } |
3304 | } |
|
|
3305 | |
3317 | |
3306 | if (who->type == PLAYER) |
3318 | if (who->type == PLAYER) |
3307 | esrv_send_item (who, tmp2); |
3319 | esrv_send_item (who, tmp2); |
3308 | |
3320 | |
3309 | return 0; |
3321 | return 0; |
… | |
… | |
3386 | } |
3398 | } |
3387 | else |
3399 | else |
3388 | new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name); |
3400 | new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name); |
3389 | } |
3401 | } |
3390 | |
3402 | |
3391 | { |
|
|
3392 | SET_FLAG (op, FLAG_APPLIED); |
3403 | SET_FLAG (op, FLAG_APPLIED); |
3393 | change_abil (who, op); |
3404 | change_abil (who, op); |
3394 | who->chosen_skill = op; |
3405 | who->chosen_skill = op; |
3395 | SET_FLAG (who, FLAG_READY_SKILL); |
3406 | SET_FLAG (who, FLAG_READY_SKILL); |
3396 | break; |
3407 | break; |
3397 | |
3408 | |
3398 | case BOW: |
3409 | case BOW: |
3399 | if (!check_weapon_power (who, op->last_eat)) |
3410 | if (!check_weapon_power (who, op->last_eat)) |
3400 | { |
3411 | { |
3401 | new_draw_info (NDI_UNIQUE, 0, who, "That item is too powerful for you to use."); |
3412 | new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use."); |
3402 | new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); |
3413 | new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); |
3403 | |
3414 | |
3404 | if (tmp) |
3415 | if (tmp) |
3405 | insert_ob_in_ob (tmp, who); |
3416 | insert_ob_in_ob (tmp, who); |
3406 | |
3417 | |
… | |
… | |
3408 | } |
3419 | } |
3409 | |
3420 | |
3410 | if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) |
3421 | if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) |
3411 | { |
3422 | { |
3412 | new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); |
3423 | new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); |
3413 | if (tmp != NULL) |
3424 | if (tmp) |
3414 | insert_ob_in_ob (tmp, who); |
3425 | insert_ob_in_ob (tmp, who); |
3415 | |
3426 | |
3416 | return 1; |
3427 | return 1; |
3417 | } |
3428 | } |
3418 | |
3429 | |