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.233 by root, Fri Apr 2 03:41:24 2010 UTC vs.
Revision 1.234 by root, Sat Apr 3 02:27:24 2010 UTC

30#include <skills.h> 30#include <skills.h>
31#include <tod.h> 31#include <tod.h>
32 32
33#include <sproto.h> 33#include <sproto.h>
34 34
35/* Want this regardless of rplay. */
36#include <sounds.h>
37
38/** 35/**
39 * Check if op should abort moving victim because of it's race or slaying. 36 * Check if op should abort moving victim because of it's race or slaying.
40 * Returns 1 if it should abort, returns 0 if it should continue. 37 * Returns 1 if it should abort, returns 0 if it should continue.
41 */ 38 */
42int 39int
1830 { 1827 {
1831 spell_skill = find_skill_by_name (op, spell->skill); 1828 spell_skill = find_skill_by_name (op, spell->skill);
1832 1829
1833 if (!spell_skill) 1830 if (!spell_skill)
1834 { 1831 {
1835 op->failmsg (format ("You lack the skill %s to use this spell.", &spell->skill)); 1832 op->failmsg (format ("You lack the %s skill to use this spell.", &spell->skill));
1836 return; 1833 return;
1837 } 1834 }
1838 1835
1839 if (spell_skill->level < spell->level) 1836 if (spell_skill->level < spell->level)
1840 { 1837 {
2777 case BOW: 2774 case BOW:
2778 case RANGED: 2775 case RANGED:
2779 case BUILDER: 2776 case BUILDER:
2780 case SKILL_TOOL: 2777 case SKILL_TOOL:
2781 if (op->env != who) 2778 if (op->env != who)
2782 return 2; /* not in inventory */ 2779 who->failmsg (format ("You must get it first! H<You can only apply the %s if it is in your inventory.>\n", query_name (op)));
2783 2780 else
2784 apply_special (who, op, aflag); 2781 apply_special (who, op, aflag);
2782
2785 return 1; 2783 return 1;
2786 2784
2787 case DRINK: 2785 case DRINK:
2788 case FOOD: 2786 case FOOD:
2789 case FLESH: 2787 case FLESH:
2853 case ITEM_TRANSFORMER: 2851 case ITEM_TRANSFORMER:
2854 apply_item_transformer (who, op); 2852 apply_item_transformer (who, op);
2855 return 1; 2853 return 1;
2856 2854
2857 default: 2855 default:
2856 who->statusmsg (format ("I don't know how to apply the %s.", query_name (op)));
2858 return 0; 2857 return 0;
2859 } 2858 }
2860} 2859}
2861 2860
2862/* quiet suppresses the "don't know how to apply" and "you must get it first" 2861/*
2863 * messages as needed by player_apply_below(). But there can still be
2864 * "but you are floating high above the ground" messages.
2865 *
2866 * Same return value as apply() function. 2862 * Same return value as apply() function.
2867 */ 2863 */
2868int 2864bool
2869player_apply (object *pl, object *op, int aflag, int quiet) 2865player_apply (object *pl, object *op, int aflag)
2870{ 2866{
2871 if (!op->env && (pl->move_type & MOVE_FLYING)) 2867 if (!op->env && (pl->move_type & MOVE_FLYING))
2872 { 2868 {
2873 /* player is flying and applying object not in inventory */ 2869 /* player is flying and applying object not in inventory */
2874 if (!QUERY_FLAG (pl, FLAG_WIZ) && !(op->move_type & MOVE_FLYING)) 2870 if (!QUERY_FLAG (pl, FLAG_WIZ) && !(op->move_type & MOVE_FLYING))
2880 } 2876 }
2881 } 2877 }
2882 2878
2883 pl->contr->last_used = op; 2879 pl->contr->last_used = op;
2884 2880
2885 int tmp = manual_apply (pl, op, aflag); 2881 return pl->apply (op, aflag);
2886
2887 if (!quiet)
2888 {
2889 if (tmp == 0)
2890 pl->statusmsg (format ("I don't know how to apply the %s.", query_name (op)));
2891 else if (tmp == 2)
2892 pl->failmsg ("You must get it first!\n");
2893 }
2894
2895 return tmp;
2896} 2882}
2897 2883
2898/** 2884/**
2899 * player_apply_below attempts to apply the object 'below' the player. 2885 * player_apply_below attempts to apply the object 'below' the player.
2900 * If the player has an open container, we use that for below, otherwise 2886 * If the player has an open container, we use that for below, otherwise
2911 * we don't use a corrupt pointer for the next object, so we get the 2897 * we don't use a corrupt pointer for the next object, so we get the
2912 * next object in the stack before applying. This is can only be a 2898 * next object in the stack before applying. This is can only be a
2913 * problem if player_apply() has a bug in that it uses the object but does 2899 * problem if player_apply() has a bug in that it uses the object but does
2914 * not return a proper value. 2900 * not return a proper value.
2915 */ 2901 */
2902 //TODO: currently looks only at the topmost objetc, no longer at multiple floors
2903 // and also not on move_on floors. what was this for, anyways?
2916 for (object *next, *tmp = pl->container_ () ? pl->container_ ()->inv : pl->below; tmp; tmp = next) 2904 for (object *next, *tmp = pl->container_ () ? pl->container_ ()->inv : pl->below; tmp; tmp = next)
2917 { 2905 {
2918 next = tmp->below; 2906 next = tmp->below;
2919 2907
2920 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR))
2921 floors++;
2922 else if (floors > 0)
2923 return; /* process only floor objects after first floor object */
2924
2925 /* If it is visible, player can apply it. If it is applied by 2908 /* If it is visible, player can apply it.
2926 * person moving on it, also activate. Added code to make it
2927 * so that at least one of players movement types be that which
2928 * the item needs.
2929 */ 2909 */
2930 if (!tmp->invisible || (tmp->move_on & pl->move_type)) 2910 if (!tmp->invisible)
2931 if (player_apply (pl, tmp, 0, 1) == 1) 2911 if (player_apply (pl, tmp, 0))
2932 return; 2912 break;
2933 2913
2934 if (floors >= 2) 2914 break;
2935 return; /* process at most two floor objects */
2936 } 2915 }
2937} 2916}
2938 2917
2939/** 2918/**
2940 * Unapplies specified item. 2919 * Unapplies specified item.
3054static object * 3033static object *
3055get_next_item_from_body_location (int loc, object *start) 3034get_next_item_from_body_location (int loc, object *start)
3056{ 3035{
3057 for (object *tmp = start; tmp; tmp = tmp->below) 3036 for (object *tmp = start; tmp; tmp = tmp->below)
3058 if (tmp->flag [FLAG_APPLIED] 3037 if (tmp->flag [FLAG_APPLIED]
3059 && tmp->slot[loc].info 3038 && tmp->slot [loc].info
3060 && (!tmp->invisible || tmp->type == SKILL)) 3039 && (!tmp->invisible || tmp->type == SKILL || tmp->type == SPELL))
3061 return tmp; 3040 return tmp;
3062 3041
3063 return 0; 3042 return 0;
3064} 3043}
3065 3044
3210 continue; 3189 continue;
3211 } 3190 }
3212 3191
3213 object *tmp1 = get_next_item_from_body_location (i, who->inv); 3192 object *tmp1 = get_next_item_from_body_location (i, who->inv);
3214 if (!tmp1) 3193 if (!tmp1)
3215 {
3216#if 0
3217 /* This is sort of an error, but happens a lot when old players
3218 * join in with more stuff equipped than they are now allowed.
3219 */
3220 LOG (llevError, "Can't find object using location %d on %s\n", i, who->name);
3221#endif
3222 retval |= CAN_APPLY_NEVER; 3194 retval |= CAN_APPLY_NEVER;
3223 }
3224 else 3195 else
3225 { 3196 {
3226 /* need to unapply something. However, if this something 3197 /* need to unapply something. However, if this something
3227 * is different than we had found before, it means they need 3198 * is different than we had found before, it means they need
3228 * to apply multiple objects 3199 * to apply multiple objects
3285 3256
3286// saner interface, returns successful status 3257// saner interface, returns successful status
3287bool 3258bool
3288object::apply (object *ob, int aflags) 3259object::apply (object *ob, int aflags)
3289{ 3260{
3290 bool want_apply = aflags & AP_APPLY; 3261 if (!ob) // simplifies a lot of callers
3291
3292 if (ob->flag [FLAG_APPLIED] == want_apply)
3293 return true; 3262 return true;
3294 3263
3264 bool want_apply =
3265 aflags & AP_APPLY ? true
3266 : aflags & AP_UNAPPLY ? false
3267 : !ob->flag [FLAG_APPLIED]; // AP_TOGGLE
3268
3269 object_ptr *slot = 0;
3270
3271 // detect the slot, if this is a player
3272 if (contr && !(aflags & AP_NO_SLOT))
3273 {
3274 switch (ob->type)
3275 {
3276 case WEAPON:
3277 slot = &contr->combat_ob;
3278 break;
3279
3280 case BOW:
3281 case RANGED:
3282 case SPELL:
3283 case WAND:
3284 case ROD:
3285 case HORN:
3286 case BUILDER:
3287 slot = &contr->ranged_ob;
3288 break;
3289
3290 // oh, the humanity
3291 case SKILL:
3292 if (aflags & AP_NO_SLOT)
3293 break;
3294
3295 if (skill_flags [ob->subtype] & SF_NEED_ITEM)
3296 break;
3297
3298 if (skill_flags [ob->subtype] & SF_COMBAT)
3299 slot = &contr->combat_ob;
3300 else if (skill_flags [ob->subtype] & SF_RANGED)
3301 slot = &contr->ranged_ob;
3302
3303 break;
3304 }
3305
3306 // clear item from slot if applied
3307 if (slot && *slot == ob && !want_apply)
3308 {
3309 *slot = 0;
3310
3311 if (current_weapon == ob)
3312 current_weapon = 0;
3313 }
3314 }
3315
3316 if (ob->flag [FLAG_APPLIED] != want_apply)
3295 manual_apply (this, ob, aflags); 3317 manual_apply (this, ob, aflags);
3296 3318
3297 return ob->flag [FLAG_APPLIED] == want_apply; 3319 if (ob->flag [FLAG_APPLIED] != want_apply)
3320 return false;
3321
3322 if (slot)
3323 current_weapon = *slot = ob;
3324
3325 return true;
3298} 3326}
3299 3327
3300/** 3328/**
3301 * who is the object using the object. It can be a monster. 3329 * who is the object using the object. It can be a monster.
3302 * op is the object they are using. op is an equipment type item, 3330 * op is the object they are using. op is an equipment type item,
3325 " H<You lack enough unused item power to use this weapon, see the skills command.>" 3353 " H<You lack enough unused item power to use this weapon, see the skills command.>"
3326 3354
3327int 3355int
3328apply_special (object *who, object *op, int aflags) 3356apply_special (object *who, object *op, int aflags)
3329{ 3357{
3330 int basic_flag = aflags & AP_BASIC_FLAGS; 3358 int basic_flag = aflags & AP_MODE;
3331 object *tmp, *tmp2, *skop = NULL; 3359 object *tmp, *tmp2, *skop = NULL;
3332 3360
3333 if (who == NULL) 3361 if (who == NULL)
3334 { 3362 {
3335 LOG (llevError, "apply_special() from object without environment.\n"); 3363 LOG (llevError, "apply_special() from object without environment.\n");
3405 if (!skop) 3433 if (!skop)
3406 { 3434 {
3407 who->failmsg (format ("You need the %s skill to use this item!", &op->skill)); 3435 who->failmsg (format ("You need the %s skill to use this item!", &op->skill));
3408 return 1; 3436 return 1;
3409 } 3437 }
3410 else if (!who->apply (skop, AP_APPLY | AP_HAVE_WEAPON)) 3438 else if (!who->apply (skop, AP_APPLY | AP_NO_SLOT))
3411 { 3439 {
3412 who->failmsg (format ("You can't use the required %s skill!", &op->skill)); 3440 who->failmsg (format ("You can't use the required %s skill!", &op->skill));
3413 return 1; 3441 return 1;
3414 } 3442 }
3415 } 3443 }
3446 3474
3447 op->flag [FLAG_APPLIED] = true; 3475 op->flag [FLAG_APPLIED] = true;
3448 3476
3449 if (player *pl = who->contr) 3477 if (player *pl = who->contr)
3450 { 3478 {
3451 who->current_weapon = pl->combat_ob = op;
3452 who->statusmsg (format ("You wield %s.", query_name (op))); 3479 who->statusmsg (format ("You wield %s.", query_name (op)));
3453 change_abil (who, op); 3480 change_abil (who, op);
3454 } 3481 }
3455 else 3482 else
3456 who->change_skill (skop); 3483 who->change_skill (skop);
3479 //TODO: unapplying should unapply the skill, though 3506 //TODO: unapplying should unapply the skill, though
3480 SET_FLAG (op, FLAG_APPLIED); 3507 SET_FLAG (op, FLAG_APPLIED);
3481 break; 3508 break;
3482 3509
3483 case SKILL: 3510 case SKILL:
3484 if (skill_flags [op->subtype] & SF_NEED_ITEM && !(aflags & AP_HAVE_WEAPON)) 3511 if (skill_flags [op->subtype] & SF_NEED_ITEM && !(aflags & AP_NO_SLOT))
3485 { 3512 {
3486 who->failmsg (format ( 3513 who->failmsg (format (
3487 "You feel as if you wanted to do something funny, but you can't remember what. " 3514 "You feel as if you wanted to do something funny, but you can't remember what. "
3488 "H<The skill %s needs an item to function, it cannot be used on its own.>", 3515 "H<The %s skill needs an item to function, it cannot be used on its own.>",
3489 &op->skill 3516 &op->skill
3490 )); 3517 ));
3491 if (tmp) who->insert (tmp); 3518 if (tmp) who->insert (tmp);
3492 return 1; 3519 return 1;
3493 } 3520 }
3494 3521
3495 if (player *pl = who->contr) 3522 if (player *pl = who->contr)
3496 { 3523 {
3497 if (skill_flags [op->subtype] & SF_COMBAT)
3498 who->current_weapon = pl->combat_ob = op;
3499
3500 if (skill_flags [op->subtype] & SF_RANGED)
3501 who->current_weapon = pl->ranged_ob = op;
3502
3503 if (op->invisible) 3524 if (op->invisible)
3504 who->statusmsg (format ("Readied skill: %s.", op->skill ? &op->skill : &op->name)); 3525 who->statusmsg (format ("Readied skill: %s.", op->skill ? &op->skill : &op->name));
3505 else 3526 else
3506 who->statusmsg (format ( 3527 who->statusmsg (format (
3507 "You ready %s." 3528 "You ready %s."
3526 } 3547 }
3527 3548
3528 if (player *pl = who->contr) 3549 if (player *pl = who->contr)
3529 { 3550 {
3530 op->flag [FLAG_APPLIED] = true; 3551 op->flag [FLAG_APPLIED] = true;
3531 who->current_weapon = pl->ranged_ob = op;
3532 who->statusmsg (format ("You wield the %s.", query_name (op))); 3552 who->statusmsg (format ("You wield the %s.", query_name (op)));
3533 change_abil (who, op); 3553 change_abil (who, op);
3534 } 3554 }
3535 break; 3555 break;
3536 3556
3537 case RANGED: 3557 case RANGED:
3538 if (player *pl = who->contr) 3558 if (player *pl = who->contr)
3539 { 3559 {
3540 op->flag [FLAG_APPLIED] = true; 3560 op->flag [FLAG_APPLIED] = true;
3541 who->current_weapon = pl->ranged_ob = op;
3542 who->statusmsg (format ("You applied the %s.", query_name (op))); 3561 who->statusmsg (format ("You applied the %s.", query_name (op)));
3543 } 3562 }
3544 break; 3563 break;
3545 3564
3546 case SPELL: 3565 case SPELL:
3547 if (player *pl = who->contr) 3566 if (player *pl = who->contr)
3548 { 3567 {
3549 op->flag [FLAG_APPLIED] = true; 3568 op->flag [FLAG_APPLIED] = true;
3550 who->current_weapon = pl->ranged_ob = op;
3551 who->statusmsg (format ("You ready the spell %s.", query_name (op))); 3569 who->statusmsg (format ("You ready the spell %s.", query_name (op)));
3552 } 3570 }
3553 break; 3571 break;
3554 3572
3555 /*FALLTHROUGH*/ 3573 /*FALLTHROUGH*/
3568 op->flag [FLAG_APPLIED] = true; 3586 op->flag [FLAG_APPLIED] = true;
3569 3587
3570 if (player *pl = who->contr) 3588 if (player *pl = who->contr)
3571 { 3589 {
3572 who->statusmsg (format ("You ready %s.", query_name (op))); 3590 who->statusmsg (format ("You ready %s.", query_name (op)));
3573 who->current_weapon = pl->ranged_ob = op;
3574 3591
3575 if (op->type == BOW) 3592 if (op->type == BOW)
3576 who->statusmsg (format ("You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op))); 3593 who->statusmsg (format ("You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op)));
3577 3594
3578 change_abil (who, op); 3595 change_abil (who, op);
3590 break; 3607 break;
3591 3608
3592 case BUILDER: 3609 case BUILDER:
3593 if (player *pl = who->contr) 3610 if (player *pl = who->contr)
3594 { 3611 {
3595 who->current_weapon = pl->ranged_ob = op;
3596 who->statusmsg (format ("You ready your %s.", query_name (op))); 3612 who->statusmsg (format ("You ready your %s.", query_name (op)));
3597 //TODO: change_abil? 3613 //TODO: change_abil?
3598 } 3614 }
3599 break; 3615 break;
3600 3616

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines