SHARE
TWEET

Archery accuracy and damage calculation

a guest Sep 4th, 2019 28 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     if (has_skill(ch, SKILL_ARCHERY))
  2.         offense = number(1, 100) + ch->skills[SKILL_ARCHERY]->learned;
  3.     else
  4.         offense = number(1, 80);
  5.  
  6.     if (max_cond >= 2.5) {
  7.         // look at weather condition
  8.         for (wn = wn_list; wn; wn = wn->next) {
  9.            // handle ch's room
  10.            if (wn->zone == ch->in_room->zone) {
  11.               max_cond = MAX(max_cond, wn->condition);
  12.               offense -= MAX(0, (wn->condition - 1.5) * 10);
  13.            }
  14.    
  15.            // if not in same room, other room
  16.            if (ch->in_room != tar_room && wn->zone == tar_room->zone) {
  17.               max_cond = MAX(max_cond, wn->condition);
  18.               offense -= MAX(0, (wn->condition - 1.5) * 10);
  19.            }
  20.         }
  21.     }
  22.     else {
  23.        // if worst condition is stormy, don't also apply wind
  24.        offense -= (weather_info.wind_velocity / 5) * 2;
  25.     }
  26.  
  27.     offense += agl_app[GET_AGL(ch)].missile;
  28.  
  29.     defense = number(1, 100) + victim->abilities.def;
  30.     defense += agl_app[GET_AGL(victim)].reaction;
  31.  
  32.     if (GET_RACE(victim) == RACE_MANTIS)
  33.         defense *= 2;
  34.  
  35.     if (n > 0)
  36.         offense -= (n * 10);
  37.  
  38.     if ((GET_RACE(victim) == RACE_GESRA) && (n > 0))
  39.         offense = 0;
  40.  
  41.     // npcs that aren't marked [archery]
  42.     if (IS_NPC(victim) && !isnamebracketsok("[archery]", MSTR(victim, name))) {
  43.         // more than 1 room away auto-fail
  44.         if (n > 1)
  45.             offense = 0;
  46.  
  47.         // sentinels always fail
  48.         if (IS_SET(victim->specials.act, CFL_SENTINEL))
  49.             offense = 0;
  50.     }
  51.  
  52.     WIPE_LDESC(ch);
  53.  
  54.     if ((dir < DIR_OUT) && (missile_wall_check(ch, arrow, dir, CMD_SHOOT)))
  55.         return;
  56.  
  57.     prior_hitpoints = GET_HIT(victim);
  58.  
  59. #ifdef RANGED_STAMINA_DRAIN
  60.     /* Stamina drain - only on bows. */
  61.     if (!bow->obj_flags.value[2]) {
  62.         staminaCost = number(1, (100 - get_skill_percentage(ch, SKILL_ARCHERY)) / 22 + 2);
  63.         if (GET_STR(ch) - bow->obj_flags.value[1] > 0) {
  64.             staminaCost -= MIN(3, GET_STR(ch) - bow->obj_flags.value[1]);
  65.         } else {                /* pulling too heavy of a bow (double penalty) */
  66.             staminaCost -= MAX(-3, GET_STR(ch) - bow->obj_flags.value[1]) * 2;
  67.         }
  68.         /* minimum of 1 cost */
  69.         adjust_move(ch, -MAX(1, staminaCost));
  70.     }
  71. #endif
  72.  
  73.     if (ch->specials.fighting && ch->specials.fighting == victim)
  74.         clear_disengage_request(ch);
  75.  
  76.     if (offense < defense) {
  77.         if (ch->in_room != victim->in_room)
  78.             alive = missile_damage(ch, victim, arrow, dir, 0, TYPE_BOW);
  79.         else
  80.             alive = ws_damage(ch, victim, 0, 0, 0, 0, TYPE_BOW, 0);
  81.  
  82.         /* high winds without skill, or offense = 0, no gain */
  83.         if (has_skill(ch, SKILL_ARCHERY) && offense > 0
  84.          && max_cond - 1.5 * 10 < get_skill_percentage(ch, SKILL_ARCHERY)) {
  85.             /* if target is asleep or paralyzed, decrease chance of learning */
  86.             if ((!AWAKE(victim) || is_paralyzed(victim)) && !number(0, 11)) {
  87.                 /* can only learn up to 40% on sparring dummies */
  88.                 if (get_skill_percentage(ch, SKILL_ARCHERY) <= 40)
  89.                     gain_skill(ch, SKILL_ARCHERY, 1);
  90.             } else {
  91.                 gain_skill(ch, SKILL_ARCHERY, 1);
  92.             }
  93.         }
  94.     } else {
  95.         is_hit = TRUE;
  96.         /* calculate damage */
  97.         if (arrow->obj_flags.type == ITEM_WEAPON) {
  98.             dam =
  99.                 dice(arrow->obj_flags.value[1],
  100.                      arrow->obj_flags.value[2]) + arrow->obj_flags.value[0];
  101.         } else {                /* not a weapon -Morg 3/12/03 */
  102.  
  103.             dam = dice(1, 2);
  104.         }
  105.  
  106.         /* strength bonus, limited str */
  107.         if (GET_STR(ch) > bow->obj_flags.value[1] + 1)
  108.             dam += str_app[bow->obj_flags.value[1]].todam;
  109.  
  110.         /* skill bonus */
  111.         if (ch->skills[SKILL_ARCHERY]) {
  112.             dam += ch->skills[SKILL_ARCHERY]->learned / 7;
  113.             if (number(0, 500) <= ch->skills[SKILL_ARCHERY]->learned)
  114.                 dam *= 2;
  115.         }
  116.  
  117.         if (ch->in_room != victim->in_room)
  118.             alive = missile_damage(ch, victim, arrow, dir, dam, TYPE_BOW);
  119.         else
  120.             alive = ws_damage(ch, victim, dam + 2, 0, 0, dam + 2, TYPE_BOW, 0);
  121.  
  122.         if (alive && IS_SET(arrow->obj_flags.extra_flags, OFL_POISON)) {
  123.             if (!does_save(victim, SAVING_PARA, 0)) {
  124.                 if (prior_hitpoints != GET_HIT(victim)) {
  125.                     /* Changed to allow new poison types - Tiernan 4/23 */
  126.                     poison_char(victim, arrow->obj_flags.value[5], number(1, (27 - GET_END(ch))),
  127.                                 0);
  128.  
  129.                     send_to_char("You feel very sick.\n\r", victim);
  130.                 }
  131.             }
  132.         }
  133.     }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top