G2A Many GEOs
SHARE
TWEET

Archery accuracy and damage calculation

a guest Sep 4th, 2019 34 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
Ledger Nano X - The secure hardware wallet
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