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.77 by root, Mon Apr 30 04:43:45 2007 UTC vs.
Revision 1.78 by root, Mon Apr 30 05:54:14 2007 UTC

2914/** 2914/**
2915 * Checks to see if 'who' can apply object 'op'. 2915 * Checks to see if 'who' can apply object 'op'.
2916 * Returns 0 if apply can be done without anything special. 2916 * Returns 0 if apply can be done without anything special.
2917 * Otherwise returns a bitmask - potentially several of these may be 2917 * Otherwise returns a bitmask - potentially several of these may be
2918 * set, but largely depends on circumstance - in the future, processing 2918 * set, but largely depends on circumstance - in the future, processing
2919 * may be pruned once we know some status (eg, once CAN_APPLY_NEVER 2919 * may be pruned once we know some status (eg, once CAN_APPLY_NEVER
2920 * is set, do we really are what the other flags may be?) 2920 * is set, do we really are what the other flags may be?)
2921 * 2921 *
2922 * See include/define.h for detailed description of the meaning of 2922 * See include/define.h for detailed description of the meaning of
2923 * these return values. 2923 * these return values.
2924 */ 2924 */
2926can_apply_object (object *who, object *op) 2926can_apply_object (object *who, object *op)
2927{ 2927{
2928 if (INVOKE_OBJECT (CAN_BE_APPLIED, op, ARG_OBJECT (who)) || INVOKE_OBJECT (CAN_APPLY, who, ARG_OBJECT (op))) 2928 if (INVOKE_OBJECT (CAN_BE_APPLIED, op, ARG_OBJECT (who)) || INVOKE_OBJECT (CAN_APPLY, who, ARG_OBJECT (op)))
2929 return RESULT_INT (0); 2929 return RESULT_INT (0);
2930 2930
2931 int i, retval = 0; 2931 int retval = 0;
2932 object *tmp = NULL, *ws = NULL; 2932 object *tmp = 0, *ws = 0;
2933 2933
2934 /* Players have 2 'arm's, so they could in theory equip 2 shields or 2934 /* Players have 2 'arm's, so they could in theory equip 2 shields or
2935 * 2 weapons, but we don't want to let them do that. So if they are 2935 * 2 weapons, but we don't want to let them do that. So if they are
2936 * trying to equip a weapon or shield, see if they already have one 2936 * trying to equip a weapon or shield, see if they already have one
2937 * in place and store that way. 2937 * in place and store that way.
2938 */ 2938 */
2939 if (op->type == WEAPON || op->type == SHIELD) 2939 if (op->type == WEAPON || op->type == BOW || op->type == SHIELD)
2940 { 2940 {
2941 for (tmp = who->inv; tmp && !ws; tmp = tmp->below) 2941 for (tmp = who->inv; tmp && !ws; tmp = tmp->below)
2942 { 2942 {
2943 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == op->type) 2943 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == op->type)
2944 { 2944 {
2946 ws = tmp; 2946 ws = tmp;
2947 } 2947 }
2948 } 2948 }
2949 } 2949 }
2950 2950
2951 for (i = 0; i < NUM_BODY_LOCATIONS; i++) 2951 for (int i = 0; i < NUM_BODY_LOCATIONS; i++)
2952 { 2952 {
2953 if (op->body_info[i]) 2953 if (op->body_info[i])
2954 { 2954 {
2955 /* Item uses more slots than we have */ 2955 /* Item uses more slots than we have */
2956 if (FABS (op->body_info[i]) > who->body_info[i]) 2956 if (abs (op->body_info[i]) > who->body_info[i])
2957 { 2957 {
2958 /* Could return now for efficiently - rest of info below isn' 2958 /* Could return now for efficiency - rest of info below isn't
2959 * really needed. 2959 * really needed.
2960 */ 2960 */
2961 retval |= CAN_APPLY_NEVER; 2961 retval |= CAN_APPLY_NEVER;
2962 } 2962 }
2963 else if ((who->body_used[i] + op->body_info[i]) < 0) 2963 else if ((who->body_used[i] + op->body_info[i]) < 0)
2964 { 2964 {
2965 /* in this case, equipping this would use more free spots than 2965 /* in this case, equipping this would use more free spots than
2966 * we have. 2966 * we have.
2967 */ 2967 */
2968 object *tmp1;
2969
2970 2968
2971 /* if we have an applied weapon/shield, and unapply it would free 2969 /* if we have an applied weapon/shield, and unapply it would free
2972 * enough slots to equip the new item, then just set this can 2970 * enough slots to equip the new item, then just set this can
2973 * continue. We don't care about the logic below - if you have 2971 * continue. We don't care about the logic below - if you have
2974 * shield equipped and try to equip another shield, there is only 2972 * shield equipped and try to equip another shield, there is only
2983 retval |= CAN_APPLY_UNAPPLY; 2981 retval |= CAN_APPLY_UNAPPLY;
2984 continue; 2982 continue;
2985 } 2983 }
2986 } 2984 }
2987 2985
2988 tmp1 = get_item_from_body_location (who->inv, i); 2986 object *tmp1 = get_item_from_body_location (who->inv, i);
2989 if (!tmp1) 2987 if (!tmp1)
2990 { 2988 {
2991#if 0 2989#if 0
2992 /* This is sort of an error, but happens a lot when old players 2990 /* This is sort of an error, but happens a lot when old players
2993 * join in with more stuff equipped than they are now allowed. 2991 * join in with more stuff equipped than they are now allowed.
3004 */ 3002 */
3005 retval |= CAN_APPLY_UNAPPLY; 3003 retval |= CAN_APPLY_UNAPPLY;
3006 if (!tmp) 3004 if (!tmp)
3007 tmp = tmp1; 3005 tmp = tmp1;
3008 else if (tmp != tmp1) 3006 else if (tmp != tmp1)
3009 {
3010 retval |= CAN_APPLY_UNAPPLY_MULT; 3007 retval |= CAN_APPLY_UNAPPLY_MULT;
3011 } 3008
3012 /* This object isn't using up all the slots, so there must 3009 /* This object isn't using up all the slots, so there must
3013 * be another. If so, and it the new item doesn't need all 3010 * be another. If so, and it the new item doesn't need all
3014 * the slots, the player then has a choice. 3011 * the slots, the player then has a choice.
3015 */ 3012 */
3016 if (((who->body_used[i] - tmp1->body_info[i]) != who->body_info[i]) && (FABS (op->body_info[i]) < who->body_info[i])) 3013 if ((who->body_used[i] - tmp1->body_info[i] != who->body_info[i])
3014 && abs (op->body_info[i]) < who->body_info[i])
3017 retval |= CAN_APPLY_UNAPPLY_CHOICE; 3015 retval |= CAN_APPLY_UNAPPLY_CHOICE;
3018 3016
3019 /* Does unequippint 'tmp1' free up enough slots for this to be 3017 /* Does unequippint 'tmp1' free up enough slots for this to be
3020 * equipped? If not, there must be something else to unapply. 3018 * equipped? If not, there must be something else to unapply.
3021 */ 3019 */
3022 if ((who->body_used[i] + op->body_info[i] - tmp1->body_info[i]) < 0) 3020 if (who->body_used[i] + op->body_info[i] < tmp1->body_info[i])
3023 retval |= CAN_APPLY_UNAPPLY_MULT; 3021 retval |= CAN_APPLY_UNAPPLY_MULT;
3024
3025 } 3022 }
3026 } /* if not enough free slots */ 3023 } /* if not enough free slots */
3027 } /* if this object uses location i */ 3024 } /* if this object uses location i */
3028 } /* for i -> num_body_locations loop */ 3025 } /* for i -> num_body_locations loop */
3029 3026
3042 3039
3043 if (who->type != PLAYER) 3040 if (who->type != PLAYER)
3044 { 3041 {
3045 if ((op->type == WAND || op->type == HORN || op->type == ROD) && !QUERY_FLAG (who, FLAG_USE_RANGE)) 3042 if ((op->type == WAND || op->type == HORN || op->type == ROD) && !QUERY_FLAG (who, FLAG_USE_RANGE))
3046 retval |= CAN_APPLY_RESTRICTION; 3043 retval |= CAN_APPLY_RESTRICTION;
3044
3047 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW)) 3045 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW))
3048 retval |= CAN_APPLY_RESTRICTION; 3046 retval |= CAN_APPLY_RESTRICTION;
3047
3049 if (op->type == RING && !QUERY_FLAG (who, FLAG_USE_RING)) 3048 if (op->type == RING && !QUERY_FLAG (who, FLAG_USE_RING))
3050 retval |= CAN_APPLY_RESTRICTION; 3049 retval |= CAN_APPLY_RESTRICTION;
3050
3051 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW)) 3051 if (op->type == BOW && !QUERY_FLAG (who, FLAG_USE_BOW))
3052 retval |= CAN_APPLY_RESTRICTION; 3052 retval |= CAN_APPLY_RESTRICTION;
3053 } 3053 }
3054 3054
3055 return retval; 3055 return retval;
3080int 3080int
3081apply_special (object *who, object *op, int aflags) 3081apply_special (object *who, object *op, int aflags)
3082{ 3082{
3083 int basic_flag = aflags & AP_BASIC_FLAGS; 3083 int basic_flag = aflags & AP_BASIC_FLAGS;
3084 object *tmp, *tmp2, *skop = NULL; 3084 object *tmp, *tmp2, *skop = NULL;
3085 int i;
3086 3085
3087 if (who == NULL) 3086 if (who == NULL)
3088 { 3087 {
3089 LOG (llevError, "apply_special() from object without environment.\n"); 3088 LOG (llevError, "apply_special() from object without environment.\n");
3090 return 1; 3089 return 1;
3103 if (!(aflags & AP_IGNORE_CURSE) && (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))) 3102 if (!(aflags & AP_IGNORE_CURSE) && (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)))
3104 { 3103 {
3105 new_draw_info_format (NDI_UNIQUE, 0, who, "No matter how hard you try, you just can't\nremove %s.", query_name (op)); 3104 new_draw_info_format (NDI_UNIQUE, 0, who, "No matter how hard you try, you just can't\nremove %s.", query_name (op));
3106 return 1; 3105 return 1;
3107 } 3106 }
3107
3108 return unapply_special (who, op, aflags); 3108 return unapply_special (who, op, aflags);
3109 } 3109 }
3110 3110
3111 if (basic_flag == AP_UNAPPLY) 3111 if (basic_flag == AP_UNAPPLY)
3112 return 0; 3112 return 0;
3113 3113
3114 i = can_apply_object (who, op);
3115
3116 /* Can't just apply this object. Lets see what not and what to do */ 3114 /* Can't just apply this object. Lets see what not and what to do */
3117 if (i) 3115 if (int i = can_apply_object (who, op))
3118 { 3116 {
3119 if (i & CAN_APPLY_NEVER) 3117 if (i & CAN_APPLY_NEVER)
3120 { 3118 {
3121 new_draw_info_format (NDI_UNIQUE, 0, who, "You don't have the body to use a %s\n", query_name (op)); 3119 new_draw_info_format (NDI_UNIQUE, 0, who, "You don't have the body to use a %s\n", query_name (op));
3122 return 1; 3120 return 1;
3124 else if (i & CAN_APPLY_RESTRICTION) 3122 else if (i & CAN_APPLY_RESTRICTION)
3125 { 3123 {
3126 new_draw_info_format (NDI_UNIQUE, 0, who, "You have a prohibition against using a %s\n", query_name (op)); 3124 new_draw_info_format (NDI_UNIQUE, 0, who, "You have a prohibition against using a %s\n", query_name (op));
3127 return 1; 3125 return 1;
3128 } 3126 }
3127
3129 if (who->type != PLAYER) 3128 if (who->type != PLAYER)
3130 { 3129 {
3131 /* Some error, so don't try to equip something more */ 3130 /* Some error, so don't try to equip something more */
3132 if (unapply_for_ob (who, op, aflags)) 3131 if (unapply_for_ob (who, op, aflags))
3133 return 1; 3132 return 1;
3140 unapply_for_ob (who, op, AP_PRINT); 3139 unapply_for_ob (who, op, AP_PRINT);
3141 return 1; 3140 return 1;
3142 } 3141 }
3143 else if (who->contr->unapply == unapply_always || !(i & CAN_APPLY_UNAPPLY_CHOICE)) 3142 else if (who->contr->unapply == unapply_always || !(i & CAN_APPLY_UNAPPLY_CHOICE))
3144 { 3143 {
3145 i = unapply_for_ob (who, op, aflags); 3144 if (unapply_for_ob (who, op, aflags))
3146 if (i)
3147 return 1; 3145 return 1;
3148 } 3146 }
3149 } 3147 }
3150 } 3148 }
3151 3149
3152 if (op->skill && op->type != SKILL && op->type != SKILL_TOOL) 3150 if (op->skill && op->type != SKILL && op->type != SKILL_TOOL)
3153 { 3151 {
3154 skop = find_skill_by_name (who, op->skill); 3152 skop = find_skill_by_name (who, op->skill);
3153
3155 if (!skop) 3154 if (!skop)
3156 { 3155 {
3157 new_draw_info_format (NDI_UNIQUE, 0, who, "You need the %s skill to use this item!", &op->skill); 3156 new_draw_info_format (NDI_UNIQUE, 0, who, "You need the %s skill to use this item!", &op->skill);
3158 return 1; 3157 return 1;
3159 } 3158 }
3162 * skill so that the dam and wc get updated 3161 * skill so that the dam and wc get updated
3163 */ 3162 */
3164 change_skill (who, skop, 0); 3163 change_skill (who, skop, 0);
3165 } 3164 }
3166 3165
3166 if (who->type == PLAYER
3167 && op->item_power
3167 if (who->type == PLAYER && op->item_power && (op->item_power + who->contr->item_power) > (settings.item_power_factor * who->level)) 3168 && op->item_power + who->contr->item_power > settings.item_power_factor * who->level)
3168 { 3169 {
3169 new_draw_info (NDI_UNIQUE, 0, who, 3170 new_draw_info (NDI_UNIQUE, 0, who,
3170 "Equipping that combined with other items would consume your soul! " 3171 "Equipping that combined with other items would consume your soul! "
3171 "[use the skills command to check your available item power]"); 3172 "[use the skills command to check your available item power]");
3172 return 1; 3173 return 1;
3173 } 3174 }
3174 3175
3175
3176 /* Ok. We are now at the state where we can apply the new object. 3176 /* Ok. We are now at the state where we can apply the new object.
3177 * Note that we don't have the checks for can_use_... 3177 * Note that we don't have the checks for can_use_...
3178 * below - that is already taken care of by can_apply_object. 3178 * below - that is already taken care of by can_apply_object.
3179 */ 3179 */
3180
3181 if (op->nrof > 1) 3180 if (op->nrof > 1)
3182 tmp = get_split_ob (op, op->nrof - 1); 3181 tmp = get_split_ob (op, op->nrof - 1);
3183 else 3182 else
3184 tmp = NULL; 3183 tmp = 0;
3185 3184
3186 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op))) 3185 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op)))
3187 return RESULT_INT (0); 3186 return RESULT_INT (0);
3188 3187
3189 switch (op->type) 3188 switch (op->type)
3191 case WEAPON: 3190 case WEAPON:
3192 if (!check_weapon_power (who, op->last_eat)) 3191 if (!check_weapon_power (who, op->last_eat))
3193 { 3192 {
3194 new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use."); 3193 new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use.");
3195 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); 3194 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!.");
3196 if (tmp != NULL) 3195 if (tmp)
3197 (void) insert_ob_in_ob (tmp, who); 3196 insert_ob_in_ob (tmp, who);
3198 return 1; 3197 return 1;
3199 } 3198 }
3200 3199
3201 //TODO: this obviously fails for players using a shiorter prefix 3200 //TODO: this obviously fails for players using a shiorter prefix
3202 // i.e. "R" can use Ragnarok's swors. 3201 // i.e. "R" can use Ragnarok's sword.
3203 if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) 3202 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3204 { 3203 {
3205 /* if the weapon does not have the name as the character, can't use it. */ 3204 /* if the weapon does not have the name as the character, can't use it. */
3206 /* (Ragnarok's sword attempted to be used by Foo: won't work) */ 3205 /* (Ragnarok's sword attempted to be used by Foo: won't work) */
3207 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); 3206 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3212 return 1; 3211 return 1;
3213 } 3212 }
3214 3213
3215 SET_FLAG (op, FLAG_APPLIED); 3214 SET_FLAG (op, FLAG_APPLIED);
3216 3215
3217 if (skop) 3216 if (!skop)
3217 new_draw_info_format (NDI_UNIQUE, 0, who, "The %s is broken, please report this to the dungeon master!", query_name (op));//TODO
3218 else//TODO
3218 change_skill (who, skop, 1); 3219 change_skill (who, skop, 1);
3220
3221 if (who->type == PLAYER)
3222 who->contr->set_skill (skop, op);
3219 3223
3220 if (!QUERY_FLAG (who, FLAG_READY_WEAPON)) 3224 if (!QUERY_FLAG (who, FLAG_READY_WEAPON))
3221 SET_FLAG (who, FLAG_READY_WEAPON); 3225 SET_FLAG (who, FLAG_READY_WEAPON);
3222 3226
3223 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op)); 3227 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op));
3241 break; 3245 break;
3242 3246
3243 case LAMP: 3247 case LAMP:
3244 if (op->stats.food < 1) 3248 if (op->stats.food < 1)
3245 { 3249 {
3246 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name); 3250 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of fuel!", &op->name);
3247 return 1; 3251 return 1;
3248 } 3252 }
3249 3253
3250 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name); 3254 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name);
3251 tmp2 = arch_to_object (op->other_arch); 3255 tmp2 = arch_to_object (op->other_arch);
3296 return 1; 3300 return 1;
3297 } 3301 }
3298 3302
3299 if (who->type == PLAYER) 3303 if (who->type == PLAYER)
3300 { 3304 {
3301 who->contr->ranged_skill = who; 3305 who->contr->set_skill (op);
3302 who->contr->ranged_ob = op;
3303 3306
3304 if (!op->invisible) 3307 if (!op->invisible)
3305 { 3308 {
3306 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); 3309 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op));
3307 new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill); 3310 new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill);
3308 } 3311 }
3309 else 3312 else
3310 new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name); 3313 new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name);
3311 } 3314 }
3312 3315
3316 if (who->type == PLAYER)
3317 who->contr->set_skill (op, 0);
3318
3313 SET_FLAG (op, FLAG_APPLIED); 3319 SET_FLAG (op, FLAG_APPLIED);
3314 change_abil (who, op); 3320 change_abil (who, op);
3315 who->chosen_skill = op; 3321 who->chosen_skill = op;
3316 SET_FLAG (who, FLAG_READY_SKILL); 3322 SET_FLAG (who, FLAG_READY_SKILL);
3317 break; 3323 break;
3341 case WAND: 3347 case WAND:
3342 case ROD: 3348 case ROD:
3343 case HORN: 3349 case HORN:
3344 /* check for skill, alter player status */ 3350 /* check for skill, alter player status */
3345 SET_FLAG (op, FLAG_APPLIED); 3351 SET_FLAG (op, FLAG_APPLIED);
3352
3346 if (skop) 3353 if (!skop)
3354 new_draw_info_format (NDI_UNIQUE, 0, who, "The %s is broken, please report this to the dungeon master!", query_name (op));//TODO
3355 else//TODO
3347 change_skill (who, skop, 0); 3356 change_skill (who, skop, 0);
3348 3357
3349 if (who->type == PLAYER) 3358 if (who->type == PLAYER)
3350 { 3359 {
3360 who->contr->set_skill (skop, op);
3361
3351 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); 3362 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op));
3352 3363
3353 if (op->type == BOW) 3364 if (op->type == BOW)
3354 { 3365 {
3355 change_abil (who, op); 3366 change_abil (who, op);
3356 new_draw_info_format (NDI_UNIQUE, 0, who, 3367 new_draw_info_format (NDI_UNIQUE, 0, who,
3357 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op)); 3368 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op));
3358 } 3369 }
3359
3360 who->contr->ranged_skill = find_skill_by_name (who, op->skill);//TODO
3361 who->contr->ranged_ob = op;
3362 } 3370 }
3363 else 3371 else
3364 { 3372 {
3365 if (op->type == BOW) 3373 if (op->type == BOW)
3366 SET_FLAG (who, FLAG_READY_BOW); 3374 SET_FLAG (who, FLAG_READY_BOW);
3587 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && tmp->has_random_items ()) 3595 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && tmp->has_random_items ())
3588 { 3596 {
3589 create_treasure (tmp->randomitems, tmp, GT_APPLY, difficulty, 0); 3597 create_treasure (tmp->randomitems, tmp, GT_APPLY, difficulty, 0);
3590 tmp->randomitems = NULL; 3598 tmp->randomitems = NULL;
3591 } 3599 }
3600
3592 // close all containers 3601 // close all containers
3593 else if (tmp->type == CONTAINER) 3602 else if (tmp->type == CONTAINER)
3594 tmp->flag [FLAG_APPLIED] = 0; 3603 tmp->flag [FLAG_APPLIED] = 0;
3595 3604
3596 tmp = above; 3605 tmp = above;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines