Advertisement
Guest User

Archery accuracy and damage calculation

a guest
Sep 4th, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.76 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement