ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/apply.C
(Generate patch)

Comparing deliantra/server/server/apply.C (file contents):
Revision 1.76 by root, Mon Apr 30 04:25:30 2007 UTC vs.
Revision 1.79 by root, Tue May 1 05:48:20 2007 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game
3 * 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 * Copyright (C) 2001 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2001 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
7 * 7 *
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * 21 *
22 * The authors can be reached via e-mail to <crossfire@schmorp.de> 22 * The authors can be reached via e-mail to <crossfire@schmorp.de>
23 */ 23 */
24 24
25#include <cmath>
26
25#include <global.h> 27#include <global.h>
26#include <living.h> 28#include <living.h>
27#include <spells.h> 29#include <spells.h>
28#include <skills.h> 30#include <skills.h>
29#include <tod.h> 31#include <tod.h>
30 32
31#include <sproto.h> 33#include <sproto.h>
32 34
33/* Want this regardless of rplay. */ 35/* Want this regardless of rplay. */
34#include <sounds.h> 36#include <sounds.h>
35
36/* need math lib for double-precision and pow() in dragon_eat_flesh() */
37#include <math.h>
38 37
39/** 38/**
40 * Check if op should abort moving victim because of it's race or slaying. 39 * Check if op should abort moving victim because of it's race or slaying.
41 * Returns 1 if it should abort, returns 0 if it should continue. 40 * Returns 1 if it should abort, returns 0 if it should continue.
42 */ 41 */
765{ 764{
766 object *otmp; 765 object *otmp;
767 766
768 if (op->type != PLAYER) 767 if (op->type != PLAYER)
769 return 0; 768 return 0;
769
770 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC)) 770 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC))
771 { 771 {
772 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the scroll."); 772 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the scroll.");
773 return 0; 773 return 0;
774 } 774 }
775
775 otmp = find_marked_object (op); 776 otmp = find_marked_object (op);
776 if (!otmp) 777 if (!otmp)
777 { 778 {
778 new_draw_info (NDI_UNIQUE, 0, op, "You need to mark a weapon object."); 779 new_draw_info (NDI_UNIQUE, 0, op, "You need to mark a weapon object.");
779 return 0; 780 return 0;
780 } 781 }
782
781 if (otmp->type != WEAPON && otmp->type != BOW) 783 if (otmp->type != WEAPON && otmp->type != BOW)
782 { 784 {
783 new_draw_info (NDI_UNIQUE, 0, op, "Marked item is not a weapon or bow"); 785 new_draw_info (NDI_UNIQUE, 0, op, "Marked item is not a weapon or bow");
784 return 0; 786 return 0;
785 } 787 }
788
786 new_draw_info (NDI_UNIQUE, 0, op, "Applied weapon builder."); 789 new_draw_info (NDI_UNIQUE, 0, op, "Applied weapon builder.");
787 improve_weapon (op, tmp, otmp); 790 improve_weapon (op, tmp, otmp);
788 esrv_send_item (op, otmp); 791 esrv_send_item (op, otmp);
789 return 1; 792 return 1;
790} 793}
2292 } 2295 }
2293 2296
2294 return 0; 2297 return 0;
2295} 2298}
2296 2299
2297
2298/** 2300/**
2299 * Main apply handler. 2301 * Main apply handler.
2300 * 2302 *
2301 * Checks for unpaid items before applying. 2303 * Checks for unpaid items before applying.
2302 * 2304 *
2309 * being applied. 2311 * being applied.
2310 * 2312 *
2311 * aflag is special (always apply/unapply) flags. Nothing is done with 2313 * aflag is special (always apply/unapply) flags. Nothing is done with
2312 * them in this function - they are passed to apply_special 2314 * them in this function - they are passed to apply_special
2313 */ 2315 */
2314
2315int 2316int
2316manual_apply (object *op, object *tmp, int aflag) 2317manual_apply (object *op, object *tmp, int aflag)
2317{ 2318{
2318 if (tmp->head) 2319 if (tmp->head)
2319 tmp = tmp->head; 2320 tmp = tmp->head;
2449 case LAMP: 2450 case LAMP:
2450 case BUILDER: 2451 case BUILDER:
2451 case SKILL_TOOL: 2452 case SKILL_TOOL:
2452 if (tmp->env != op) 2453 if (tmp->env != op)
2453 return 2; /* not in inventory */ 2454 return 2; /* not in inventory */
2455
2454 (void) apply_special (op, tmp, aflag); 2456 apply_special (op, tmp, aflag);
2455 return 1; 2457 return 1;
2456 2458
2457 case DRINK: 2459 case DRINK:
2458 case FOOD: 2460 case FOOD:
2459 case FLESH: 2461 case FLESH:
2643 switch (op->type) 2645 switch (op->type)
2644 { 2646 {
2645 case WEAPON: 2647 case WEAPON:
2646 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwield %s.", query_name (op)); 2648 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwield %s.", query_name (op));
2647 2649
2648 (void) change_abil (who, op); 2650 change_abil (who, op);
2649 if (QUERY_FLAG (who, FLAG_READY_WEAPON))
2650 CLEAR_FLAG (who, FLAG_READY_WEAPON); 2651 CLEAR_FLAG (who, FLAG_READY_WEAPON);
2652
2653 if (who->contr)
2654 {
2655 if (who->contr->combat_ob == op)
2656 who->contr->combat_ob = 0;
2657
2658 if (who->current_weapon == op)
2659 who->current_weapon = 0;
2660 }
2661
2651 clear_skill (who); 2662 clear_skill (who);
2652 break; 2663 break;
2653 2664
2654 case SKILL: /* allows objects to impart skills */ 2665 case SKILL: /* allows objects to impart skills */
2655 case SKILL_TOOL: 2666 case SKILL_TOOL:
2656 if (op != who->chosen_skill) 2667 if (op != who->chosen_skill)
2657 LOG (llevError, "BUG: apply_special(): applied skill is not a chosen skill\n"); 2668 LOG (llevError, "BUG: apply_special(): applied skill is not a chosen skill\n");
2658 2669
2659 if (who->type == PLAYER) 2670 if (who->contr)
2660 {
2661 if (who->contr->ranged_ob == op)
2662 { 2671 {
2663 who->contr->ranged_skill = 0;
2664 who->contr->ranged_ob = 0;
2665 }
2666
2667 if (!op->invisible) 2672 if (!op->invisible)
2668 new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op)); 2673 new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op));
2669 else 2674 else
2670 new_draw_info_format (NDI_UNIQUE, 0, who, "You can no longer use the skill: %s.", &op->skill); 2675 new_draw_info_format (NDI_UNIQUE, 0, who, "You can no longer use the skill: %s.", &op->skill);
2671 } 2676 }
2684 case AMULET: 2689 case AMULET:
2685 case GIRDLE: 2690 case GIRDLE:
2686 case BRACERS: 2691 case BRACERS:
2687 case CLOAK: 2692 case CLOAK:
2688 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwear %s.", query_name (op)); 2693 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwear %s.", query_name (op));
2689 (void) change_abil (who, op); 2694 change_abil (who, op);
2690 break; 2695 break;
2696
2691 case LAMP: 2697 case LAMP:
2692 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn off your %s.", &op->name); 2698 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn off your %s.", &op->name);
2693 tmp2 = arch_to_object (op->other_arch); 2699 tmp2 = arch_to_object (op->other_arch);
2694 tmp2->x = op->x; 2700 tmp2->x = op->x;
2695 tmp2->y = op->y; 2701 tmp2->y = op->y;
2700 CLEAR_FLAG (tmp2, FLAG_APPLIED); 2706 CLEAR_FLAG (tmp2, FLAG_APPLIED);
2701 2707
2702 if (QUERY_FLAG (op, FLAG_INV_LOCKED)) 2708 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
2703 SET_FLAG (tmp2, FLAG_INV_LOCKED); 2709 SET_FLAG (tmp2, FLAG_INV_LOCKED);
2704 2710
2705 if (who->type == PLAYER) 2711 if (who->contr)
2706 esrv_del_item (who->contr, op->count); 2712 esrv_del_item (who->contr, op->count);
2707 2713
2708 op->destroy (); 2714 op->destroy ();
2709 insert_ob_in_ob (tmp2, who); 2715 insert_ob_in_ob (tmp2, who);
2710 who->update_stats (); 2716 who->update_stats ();
2717
2711 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 2718 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2712 { 2719 {
2713 if (who->type == PLAYER) 2720 if (who->contr)
2714 { 2721 {
2715 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); 2722 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
2716 SET_FLAG (tmp2, FLAG_KNOWN_CURSED); 2723 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
2717 } 2724 }
2718 } 2725 }
2719 if (who->type == PLAYER) 2726
2727 if (who->contr)
2720 esrv_send_item (who, tmp2); 2728 esrv_send_item (who, tmp2);
2729
2721 return 1; /* otherwise, an attempt to drop causes problems */ 2730 return 1; /* otherwise, an attempt to drop causes problems */
2722 break;
2723 2731
2724 case BOW: 2732 case BOW:
2725 case WAND: 2733 case WAND:
2726 case ROD: 2734 case ROD:
2727 case HORN: 2735 case HORN:
2728 clear_skill (who); 2736 clear_skill (who);
2729 if (who->type == PLAYER) 2737
2738 if (who->contr)
2730 { 2739 {
2731 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op)); 2740 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2732 2741
2733 who->contr->ranged_skill = 0; 2742 if (who->contr->ranged_ob == op)
2734 who->contr->ranged_ob = 0; 2743 who->contr->ranged_ob = 0;
2744
2745 if (who->current_weapon == op)
2746 who->current_weapon = 0;
2735 } 2747 }
2736 else 2748 else
2737 { 2749 {
2738 if (op->type == BOW) 2750 if (op->type == BOW)
2739 CLEAR_FLAG (who, FLAG_READY_BOW); 2751 CLEAR_FLAG (who, FLAG_READY_BOW);
2742 } 2754 }
2743 2755
2744 break; 2756 break;
2745 2757
2746 case BUILDER: 2758 case BUILDER:
2747 if (who->type == PLAYER) 2759 if (who->contr)
2748 { 2760 {
2749 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op)); 2761 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2750 2762
2751 who->contr->ranged_skill = 0; 2763 if (who->contr->ranged_ob == op)
2752 who->contr->ranged_ob = 0; 2764 who->contr->ranged_ob = 0;
2753 } 2765 }
2754 break; 2766 break;
2755 2767
2756 default: 2768 default:
2757 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op)); 2769 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op));
2763 if (!(aflags & AP_NO_MERGE)) 2775 if (!(aflags & AP_NO_MERGE))
2764 { 2776 {
2765 object *tmp; 2777 object *tmp;
2766 2778
2767 tmp = merge_ob (op, NULL); 2779 tmp = merge_ob (op, NULL);
2768 if (who->type == PLAYER) 2780
2781 if (who->contr)
2769 { 2782 {
2770 if (tmp) 2783 if (tmp)
2771 { /* it was merged */ 2784 { /* it was merged */
2772 esrv_del_item (who->contr, op->count); 2785 esrv_del_item (who->contr, op->count);
2773 op = tmp; 2786 op = tmp;
2774 } 2787 }
2775 2788
2776 esrv_send_item (who, op); 2789 esrv_send_item (who, op);
2777 } 2790 }
2778 } 2791 }
2792
2779 return 0; 2793 return 0;
2780} 2794}
2781 2795
2782/** 2796/**
2783 * Returns the object that is using location 'loc'. 2797 * Returns the object that is using location 'loc'.
2910/** 2924/**
2911 * Checks to see if 'who' can apply object 'op'. 2925 * Checks to see if 'who' can apply object 'op'.
2912 * Returns 0 if apply can be done without anything special. 2926 * Returns 0 if apply can be done without anything special.
2913 * Otherwise returns a bitmask - potentially several of these may be 2927 * Otherwise returns a bitmask - potentially several of these may be
2914 * set, but largely depends on circumstance - in the future, processing 2928 * set, but largely depends on circumstance - in the future, processing
2915 * may be pruned once we know some status (eg, once CAN_APPLY_NEVER 2929 * may be pruned once we know some status (eg, once CAN_APPLY_NEVER
2916 * is set, do we really are what the other flags may be?) 2930 * is set, do we really are what the other flags may be?)
2917 * 2931 *
2918 * See include/define.h for detailed description of the meaning of 2932 * See include/define.h for detailed description of the meaning of
2919 * these return values. 2933 * these return values.
2920 */ 2934 */
2922can_apply_object (object *who, object *op) 2936can_apply_object (object *who, object *op)
2923{ 2937{
2924 if (INVOKE_OBJECT (CAN_BE_APPLIED, op, ARG_OBJECT (who)) || INVOKE_OBJECT (CAN_APPLY, who, ARG_OBJECT (op))) 2938 if (INVOKE_OBJECT (CAN_BE_APPLIED, op, ARG_OBJECT (who)) || INVOKE_OBJECT (CAN_APPLY, who, ARG_OBJECT (op)))
2925 return RESULT_INT (0); 2939 return RESULT_INT (0);
2926 2940
2927 int i, retval = 0; 2941 int retval = 0;
2928 object *tmp = NULL, *ws = NULL; 2942 object *tmp = 0, *ws = 0;
2929 2943
2930 /* Players have 2 'arm's, so they could in theory equip 2 shields or 2944 /* Players have 2 'arm's, so they could in theory equip 2 shields or
2931 * 2 weapons, but we don't want to let them do that. So if they are 2945 * 2 weapons, but we don't want to let them do that. So if they are
2932 * trying to equip a weapon or shield, see if they already have one 2946 * trying to equip a weapon or shield, see if they already have one
2933 * in place and store that way. 2947 * in place and store that way.
2934 */ 2948 */
2935 if (op->type == WEAPON || op->type == SHIELD) 2949 if (op->type == WEAPON || op->type == BOW || op->type == SHIELD)
2936 { 2950 {
2937 for (tmp = who->inv; tmp && !ws; tmp = tmp->below) 2951 for (tmp = who->inv; tmp && !ws; tmp = tmp->below)
2938 { 2952 {
2939 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == op->type) 2953 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == op->type)
2940 { 2954 {
2942 ws = tmp; 2956 ws = tmp;
2943 } 2957 }
2944 } 2958 }
2945 } 2959 }
2946 2960
2947 for (i = 0; i < NUM_BODY_LOCATIONS; i++) 2961 for (int i = 0; i < NUM_BODY_LOCATIONS; i++)
2948 { 2962 {
2949 if (op->body_info[i]) 2963 if (op->body_info[i])
2950 { 2964 {
2951 /* Item uses more slots than we have */ 2965 /* Item uses more slots than we have */
2952 if (FABS (op->body_info[i]) > who->body_info[i]) 2966 if (abs (op->body_info[i]) > who->body_info[i])
2953 { 2967 {
2954 /* Could return now for efficiently - rest of info below isn' 2968 /* Could return now for efficiency - rest of info below isn't
2955 * really needed. 2969 * really needed.
2956 */ 2970 */
2957 retval |= CAN_APPLY_NEVER; 2971 retval |= CAN_APPLY_NEVER;
2958 } 2972 }
2959 else if ((who->body_used[i] + op->body_info[i]) < 0) 2973 else if ((who->body_used[i] + op->body_info[i]) < 0)
2960 { 2974 {
2961 /* in this case, equipping this would use more free spots than 2975 /* in this case, equipping this would use more free spots than
2962 * we have. 2976 * we have.
2963 */ 2977 */
2964 object *tmp1;
2965
2966 2978
2967 /* if we have an applied weapon/shield, and unapply it would free 2979 /* if we have an applied weapon/shield, and unapply it would free
2968 * enough slots to equip the new item, then just set this can 2980 * enough slots to equip the new item, then just set this can
2969 * continue. We don't care about the logic below - if you have 2981 * continue. We don't care about the logic below - if you have
2970 * shield equipped and try to equip another shield, there is only 2982 * shield equipped and try to equip another shield, there is only
2979 retval |= CAN_APPLY_UNAPPLY; 2991 retval |= CAN_APPLY_UNAPPLY;
2980 continue; 2992 continue;
2981 } 2993 }
2982 } 2994 }
2983 2995
2984 tmp1 = get_item_from_body_location (who->inv, i); 2996 object *tmp1 = get_item_from_body_location (who->inv, i);
2985 if (!tmp1) 2997 if (!tmp1)
2986 { 2998 {
2987#if 0 2999#if 0
2988 /* This is sort of an error, but happens a lot when old players 3000 /* This is sort of an error, but happens a lot when old players
2989 * join in with more stuff equipped than they are now allowed. 3001 * join in with more stuff equipped than they are now allowed.
3000 */ 3012 */
3001 retval |= CAN_APPLY_UNAPPLY; 3013 retval |= CAN_APPLY_UNAPPLY;
3002 if (!tmp) 3014 if (!tmp)
3003 tmp = tmp1; 3015 tmp = tmp1;
3004 else if (tmp != tmp1) 3016 else if (tmp != tmp1)
3005 {
3006 retval |= CAN_APPLY_UNAPPLY_MULT; 3017 retval |= CAN_APPLY_UNAPPLY_MULT;
3007 } 3018
3008 /* This object isn't using up all the slots, so there must 3019 /* This object isn't using up all the slots, so there must
3009 * be another. If so, and it the new item doesn't need all 3020 * be another. If so, and it the new item doesn't need all
3010 * the slots, the player then has a choice. 3021 * the slots, the player then has a choice.
3011 */ 3022 */
3012 if (((who->body_used[i] - tmp1->body_info[i]) != who->body_info[i]) && (FABS (op->body_info[i]) < who->body_info[i])) 3023 if ((who->body_used[i] - tmp1->body_info[i] != who->body_info[i])
3024 && abs (op->body_info[i]) < who->body_info[i])
3013 retval |= CAN_APPLY_UNAPPLY_CHOICE; 3025 retval |= CAN_APPLY_UNAPPLY_CHOICE;
3014 3026
3015 /* Does unequippint 'tmp1' free up enough slots for this to be 3027 /* Does unequippint 'tmp1' free up enough slots for this to be
3016 * equipped? If not, there must be something else to unapply. 3028 * equipped? If not, there must be something else to unapply.
3017 */ 3029 */
3018 if ((who->body_used[i] + op->body_info[i] - tmp1->body_info[i]) < 0) 3030 if (who->body_used[i] + op->body_info[i] < tmp1->body_info[i])
3019 retval |= CAN_APPLY_UNAPPLY_MULT; 3031 retval |= CAN_APPLY_UNAPPLY_MULT;
3020
3021 } 3032 }
3022 } /* if not enough free slots */ 3033 } /* if not enough free slots */
3023 } /* if this object uses location i */ 3034 } /* if this object uses location i */
3024 } /* for i -> num_body_locations loop */ 3035 } /* for i -> num_body_locations loop */
3025 3036
3038 3049
3039 if (who->type != PLAYER) 3050 if (who->type != PLAYER)
3040 { 3051 {
3041 if ((op->type == WAND || op->type == HORN || op->type == ROD) && !QUERY_FLAG (who, FLAG_USE_RANGE)) 3052 if ((op->type == WAND || op->type == HORN || op->type == ROD) && !QUERY_FLAG (who, FLAG_USE_RANGE))
3042 retval |= CAN_APPLY_RESTRICTION; 3053 retval |= CAN_APPLY_RESTRICTION;
3054
3043 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW)) 3055 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW))
3044 retval |= CAN_APPLY_RESTRICTION; 3056 retval |= CAN_APPLY_RESTRICTION;
3057
3045 if (op->type == RING && !QUERY_FLAG (who, FLAG_USE_RING)) 3058 if (op->type == RING && !QUERY_FLAG (who, FLAG_USE_RING))
3046 retval |= CAN_APPLY_RESTRICTION; 3059 retval |= CAN_APPLY_RESTRICTION;
3060
3047 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW)) 3061 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW))
3048 retval |= CAN_APPLY_RESTRICTION; 3062 retval |= CAN_APPLY_RESTRICTION;
3049 } 3063 }
3050 3064
3051 return retval; 3065 return retval;
3076int 3090int
3077apply_special (object *who, object *op, int aflags) 3091apply_special (object *who, object *op, int aflags)
3078{ 3092{
3079 int basic_flag = aflags & AP_BASIC_FLAGS; 3093 int basic_flag = aflags & AP_BASIC_FLAGS;
3080 object *tmp, *tmp2, *skop = NULL; 3094 object *tmp, *tmp2, *skop = NULL;
3081 int i;
3082 3095
3083 if (who == NULL) 3096 if (who == NULL)
3084 { 3097 {
3085 LOG (llevError, "apply_special() from object without environment.\n"); 3098 LOG (llevError, "apply_special() from object without environment.\n");
3086 return 1; 3099 return 1;
3099 if (!(aflags & AP_IGNORE_CURSE) && (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))) 3112 if (!(aflags & AP_IGNORE_CURSE) && (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)))
3100 { 3113 {
3101 new_draw_info_format (NDI_UNIQUE, 0, who, "No matter how hard you try, you just can't\nremove %s.", query_name (op)); 3114 new_draw_info_format (NDI_UNIQUE, 0, who, "No matter how hard you try, you just can't\nremove %s.", query_name (op));
3102 return 1; 3115 return 1;
3103 } 3116 }
3117
3104 return unapply_special (who, op, aflags); 3118 return unapply_special (who, op, aflags);
3105 } 3119 }
3106 3120
3107 if (basic_flag == AP_UNAPPLY) 3121 if (basic_flag == AP_UNAPPLY)
3108 return 0; 3122 return 0;
3109 3123
3110 i = can_apply_object (who, op);
3111
3112 /* Can't just apply this object. Lets see what not and what to do */ 3124 /* Can't just apply this object. Lets see what not and what to do */
3113 if (i) 3125 if (int i = can_apply_object (who, op))
3114 { 3126 {
3115 if (i & CAN_APPLY_NEVER) 3127 if (i & CAN_APPLY_NEVER)
3116 { 3128 {
3117 new_draw_info_format (NDI_UNIQUE, 0, who, "You don't have the body to use a %s\n", query_name (op)); 3129 new_draw_info_format (NDI_UNIQUE, 0, who, "You don't have the body to use a %s\n", query_name (op));
3118 return 1; 3130 return 1;
3120 else if (i & CAN_APPLY_RESTRICTION) 3132 else if (i & CAN_APPLY_RESTRICTION)
3121 { 3133 {
3122 new_draw_info_format (NDI_UNIQUE, 0, who, "You have a prohibition against using a %s\n", query_name (op)); 3134 new_draw_info_format (NDI_UNIQUE, 0, who, "You have a prohibition against using a %s\n", query_name (op));
3123 return 1; 3135 return 1;
3124 } 3136 }
3137
3125 if (who->type != PLAYER) 3138 if (who->type != PLAYER)
3126 { 3139 {
3127 /* Some error, so don't try to equip something more */ 3140 /* Some error, so don't try to equip something more */
3128 if (unapply_for_ob (who, op, aflags)) 3141 if (unapply_for_ob (who, op, aflags))
3129 return 1; 3142 return 1;
3136 unapply_for_ob (who, op, AP_PRINT); 3149 unapply_for_ob (who, op, AP_PRINT);
3137 return 1; 3150 return 1;
3138 } 3151 }
3139 else if (who->contr->unapply == unapply_always || !(i & CAN_APPLY_UNAPPLY_CHOICE)) 3152 else if (who->contr->unapply == unapply_always || !(i & CAN_APPLY_UNAPPLY_CHOICE))
3140 { 3153 {
3141 i = unapply_for_ob (who, op, aflags); 3154 if (unapply_for_ob (who, op, aflags))
3142 if (i)
3143 return 1; 3155 return 1;
3144 } 3156 }
3145 } 3157 }
3146 } 3158 }
3147 3159
3148 if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) 3160 if (op->skill && op->type != SKILL && op->type != SKILL_TOOL)
3149 { 3161 {
3150 skop = find_skill_by_name (who, op->skill); 3162 skop = find_skill_by_name (who, op->skill);
3163
3151 if (!skop) 3164 if (!skop)
3152 { 3165 {
3153 new_draw_info_format (NDI_UNIQUE, 0, who, "You need the %s skill to use this item!", &op->skill); 3166 new_draw_info_format (NDI_UNIQUE, 0, who, "You need the %s skill to use this item!", &op->skill);
3154 return 1; 3167 return 1;
3155 } 3168 }
3158 * skill so that the dam and wc get updated 3171 * skill so that the dam and wc get updated
3159 */ 3172 */
3160 change_skill (who, skop, 0); 3173 change_skill (who, skop, 0);
3161 } 3174 }
3162 3175
3176 if (who->type == PLAYER
3177 && op->item_power
3163 if (who->type == PLAYER && op->item_power && (op->item_power + who->contr->item_power) > (settings.item_power_factor * who->level)) 3178 && op->item_power + who->contr->item_power > settings.item_power_factor * who->level)
3164 { 3179 {
3165 new_draw_info (NDI_UNIQUE, 0, who, 3180 new_draw_info (NDI_UNIQUE, 0, who,
3166 "Equipping that combined with other items would consume your soul! " 3181 "Equipping that combined with other items would consume your soul! "
3167 "[use the skills command to check your available item power]"); 3182 "[use the skills command to check your available item power]");
3168 return 1; 3183 return 1;
3169 } 3184 }
3170 3185
3171
3172 /* Ok. We are now at the state where we can apply the new object. 3186 /* Ok. We are now at the state where we can apply the new object.
3173 * Note that we don't have the checks for can_use_... 3187 * Note that we don't have the checks for can_use_...
3174 * below - that is already taken care of by can_apply_object. 3188 * below - that is already taken care of by can_apply_object.
3175 */ 3189 */
3176
3177 if (op->nrof > 1) 3190 if (op->nrof > 1)
3178 tmp = get_split_ob (op, op->nrof - 1); 3191 tmp = get_split_ob (op, op->nrof - 1);
3179 else 3192 else
3180 tmp = NULL; 3193 tmp = 0;
3181 3194
3182 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op))) 3195 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op)))
3183 return RESULT_INT (0); 3196 return RESULT_INT (0);
3184 3197
3185 switch (op->type) 3198 switch (op->type)
3187 case WEAPON: 3200 case WEAPON:
3188 if (!check_weapon_power (who, op->last_eat)) 3201 if (!check_weapon_power (who, op->last_eat))
3189 { 3202 {
3190 new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use."); 3203 new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use.");
3191 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); 3204 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!.");
3205
3192 if (tmp != NULL) 3206 if (tmp)
3193 (void) insert_ob_in_ob (tmp, who); 3207 insert_ob_in_ob (tmp, who);
3208
3194 return 1; 3209 return 1;
3195 } 3210 }
3196 3211
3197 //TODO: this obviously fails for players using a shiorter prefix 3212 //TODO: this obviously fails for players using a shorter prefix
3198 // i.e. "R" can use Ragnarok's swors. 3213 // i.e. "R" can use Ragnarok's sword.
3199 if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) 3214 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3200 { 3215 {
3201 /* if the weapon does not have the name as the character, can't use it. */ 3216 /* if the weapon does not have the name as the character, can't use it. */
3202 /* (Ragnarok's sword attempted to be used by Foo: won't work) */ 3217 /* (Ragnarok's sword attempted to be used by Foo: won't work) */
3203 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); 3218 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3208 return 1; 3223 return 1;
3209 } 3224 }
3210 3225
3211 SET_FLAG (op, FLAG_APPLIED); 3226 SET_FLAG (op, FLAG_APPLIED);
3212 3227
3213 if (skop) 3228 if (!skop)
3229 new_draw_info_format (NDI_UNIQUE, 0, who, "The %s is broken, please report this to the dungeon master!", query_name (op));//TODO
3230 else//TODO
3214 change_skill (who, skop, 1); 3231 change_skill (who, skop, 1);
3232
3233 if (who->contr)
3234 {
3235 who->contr->combat_ob = op;
3236 who->current_weapon = op;
3237 }
3215 3238
3216 if (!QUERY_FLAG (who, FLAG_READY_WEAPON)) 3239 if (!QUERY_FLAG (who, FLAG_READY_WEAPON))
3217 SET_FLAG (who, FLAG_READY_WEAPON); 3240 SET_FLAG (who, FLAG_READY_WEAPON);
3218 3241
3219 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op)); 3242 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op));
3237 break; 3260 break;
3238 3261
3239 case LAMP: 3262 case LAMP:
3240 if (op->stats.food < 1) 3263 if (op->stats.food < 1)
3241 { 3264 {
3242 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name); 3265 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of fuel!", &op->name);
3243 return 1; 3266 return 1;
3244 } 3267 }
3245 3268
3246 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name); 3269 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name);
3247 tmp2 = arch_to_object (op->other_arch); 3270 tmp2 = arch_to_object (op->other_arch);
3290 { 3313 {
3291 LOG (llevError, "BUG: apply_special(): can't apply two skills\n"); 3314 LOG (llevError, "BUG: apply_special(): can't apply two skills\n");
3292 return 1; 3315 return 1;
3293 } 3316 }
3294 3317
3295 if (who->type == PLAYER) 3318 if (player *pl = who->contr)
3319 {
3320 if (IS_COMBAT_SKILL (op->subtype))
3296 { 3321 {
3297 who->contr->ranged_skill = who; 3322 if (skill_flags [op->subtype] && SF_NEED_WEAPON)
3323 {
3324 for (object *item = who->inv; item; item = item->below)
3325 if (item->type == WEAPON && item->flag [FLAG_APPLIED])
3326 {
3327 pl->combat_ob = who->current_weapon = item;
3328 goto found_weapon;
3329 }
3330
3331 new_draw_info (NDI_UNIQUE, 0, who, "You need to apply a melee weapon before readying this skill");
3332 return 1;
3333
3334 found_weapon:;
3335 }
3336 else
3298 who->contr->ranged_ob = op; 3337 who->contr->combat_ob = op;
3338 }
3339 else if (IS_RANGED_SKILL (op->subtype))
3340 {
3341 if (skill_flags [op->subtype] && SF_NEED_BOW)
3342 {
3343 for (object *item = who->inv; item; item = item->below)
3344 if (item->type == BOW && item->flag [FLAG_APPLIED])
3345 {
3346 pl->ranged_ob = who->current_weapon = item;
3347 goto found_bow;
3348 }
3349
3350 new_draw_info (NDI_UNIQUE, 0, who, "You need to apply a missile weapon before readying this skill");
3351 return 1;
3352
3353 found_bow:;
3354 }
3355 else if (skill_flags [op->subtype] && SF_NEED_ITEM)
3356 {
3357 for (object *item = who->inv; item; item = item->below)
3358 if (item->flag [FLAG_APPLIED]
3359 && (item->type == WAND || item->type == ROD || item->type == HORN))
3360 {
3361 pl->ranged_ob = who->current_weapon = item;
3362 goto found_item;
3363 }
3364
3365 new_draw_info (NDI_UNIQUE, 0, who, "You need to apply a magic item before readying this skill");
3366 return 1;
3367
3368 found_item:;
3369 }
3370 else
3371 pl->ranged_ob = op;
3372 }
3299 3373
3300 if (!op->invisible) 3374 if (!op->invisible)
3301 { 3375 {
3302 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); 3376 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op));
3303 new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill); 3377 new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill);
3337 case WAND: 3411 case WAND:
3338 case ROD: 3412 case ROD:
3339 case HORN: 3413 case HORN:
3340 /* check for skill, alter player status */ 3414 /* check for skill, alter player status */
3341 SET_FLAG (op, FLAG_APPLIED); 3415 SET_FLAG (op, FLAG_APPLIED);
3416
3342 if (skop) 3417 if (!skop)
3418 new_draw_info_format (NDI_UNIQUE, 0, who, "The %s is broken, please report this to the dungeon master!", query_name (op));//TODO
3419 else//TODO
3343 change_skill (who, skop, 0); 3420 change_skill (who, skop, 0);
3344 3421
3345 if (who->type == PLAYER) 3422 if (who->contr)
3346 { 3423 {
3424 who->contr->ranged_ob = op;
3425
3347 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); 3426 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op));
3348 3427
3349 if (op->type == BOW) 3428 if (op->type == BOW)
3350 { 3429 {
3430 who->current_weapon = op;
3351 change_abil (who, op); 3431 change_abil (who, op);
3352 new_draw_info_format (NDI_UNIQUE, 0, who, 3432 new_draw_info_format (NDI_UNIQUE, 0, who,
3353 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op)); 3433 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op));
3354 } 3434 }
3355
3356 who->contr->ranged_skill = find_skill_by_name (who, op->skill);//TODO
3357 who->contr->ranged_ob = op;
3358 } 3435 }
3359 else 3436 else
3360 { 3437 {
3361 if (op->type == BOW) 3438 if (op->type == BOW)
3362 SET_FLAG (who, FLAG_READY_BOW); 3439 SET_FLAG (who, FLAG_READY_BOW);
3372 if (who->contr->ranged_ob && who->contr->ranged_ob->type == BUILDER) 3449 if (who->contr->ranged_ob && who->contr->ranged_ob->type == BUILDER)
3373 unapply_special (who, who->contr->ranged_ob, 0); 3450 unapply_special (who, who->contr->ranged_ob, 0);
3374 3451
3375 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op)); 3452 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op));
3376 3453
3377 who->contr->ranged_skill = who;
3378 who->contr->ranged_ob = op; 3454 who->contr->ranged_ob = op;
3379 } 3455 }
3380 break; 3456 break;
3381 3457
3382 default: 3458 default:
3383 new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op)); 3459 new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op));
3384 } /* end of switch op->type */ 3460 } /* end of switch op->type */
3385 3461
3386 SET_FLAG (op, FLAG_APPLIED); 3462 SET_FLAG (op, FLAG_APPLIED);
3387 3463
3388 if (tmp != NULL) 3464 if (tmp)
3389 tmp = insert_ob_in_ob (tmp, who); 3465 tmp = insert_ob_in_ob (tmp, who);
3390 3466
3391 who->update_stats (); 3467 who->update_stats ();
3392 3468
3393 /* We exclude spell casting objects. The fire code will set the 3469 /* We exclude spell casting objects. The fire code will set the
3583 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && tmp->has_random_items ()) 3659 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && tmp->has_random_items ())
3584 { 3660 {
3585 create_treasure (tmp->randomitems, tmp, GT_APPLY, difficulty, 0); 3661 create_treasure (tmp->randomitems, tmp, GT_APPLY, difficulty, 0);
3586 tmp->randomitems = NULL; 3662 tmp->randomitems = NULL;
3587 } 3663 }
3664
3588 // close all containers 3665 // close all containers
3589 else if (tmp->type == CONTAINER) 3666 else if (tmp->type == CONTAINER)
3590 tmp->flag [FLAG_APPLIED] = 0; 3667 tmp->flag [FLAG_APPLIED] = 0;
3591 3668
3592 tmp = above; 3669 tmp = above;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines