Advertisement
NovaRain

FO2 To-Hit Calculation

Jul 13th, 2017
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.60 KB | None | 0 0
  1. // PSEUDOCODE
  2.  
  3. // determining tohit:
  4.  
  5. // used GLOBALLY in calculations (all =0 as default):
  6.  
  7. int distmod1;
  8. int distmod2;
  9. int dist; // used as accumulator
  10. int tohit;
  11. int use_ac; // is armor class used
  12. int is_ranged; // is attack ranged
  13. int perception;
  14.  
  15.  
  16. int determine_tohit_func() {
  17.  
  18.   if (target_valid) use_ac = 1; // target_valid <=> target_id != 0
  19.  
  20.   if (attack_is_generic_fo1_unarmed_attack) tohit = attacker_skill_unarmed;
  21.     else
  22.     if (attack_with_weapon) {
  23.       tohit = attacker_skill_appropriate; // checked for small guns etc.
  24.  
  25.       if (weapon_is_ranged) apply_distance_modifier(); // this will also mark the attack as ranged
  26.  
  27.       if (attacker_is_player)
  28.         if (player_is_one_hander)
  29.           { if (weapon_is_two_handed) tohit-=40; else tohit+=20; }
  30.  
  31.       int strength=attacker_stat_strength;
  32.       if (attacker_is_player)
  33.         if (player_have_weapon_handling) strength+=3;
  34.       if (weapon_strength_req > strength) tohit-=20*(weapon_strength_req - strength);
  35.  
  36.       if (weapon_perk == accurate) tohit+=20;
  37.     }
  38.     else
  39.     if (attack_without_weapon) tohit = attacker_skill_unarmed; // fo2 attacks without weapons (including special punches etc.)
  40.   // if attack_type == invalid then tohit == 0, still.
  41.  
  42.   if (use_ac)
  43.     if (target_ac + weapon_ac_mod > 0) tohit -= target_ac + weapon_ac_mod; // weapon_ac_mod is usually negative
  44.  
  45.   if (attack_is_ranged) tohit+=location_penalty; // which is negative
  46.     else tohit+=location_penalty/2;
  47.  
  48.   if (target_is_multihex) tohit+=15; // centaurs, deathclaws etc.
  49.  
  50.   if (attacker_is_player) {
  51.     int light;
  52.     if (!target_valid) light=0;
  53.     else {
  54.       light = target_lumination;
  55.       if (weapon_perk == night_sight) light=0x10000;
  56.     }
  57.     if (0x9999 < light <= 0x0cccc) tohit-=10;
  58.     if (0x6666 < light <= 0x9999)  tohit-=25;
  59.     if (         light <= 0x6666)  tohit-=40;
  60.   } // light is not applied for npcs
  61.  
  62.   if (attacker_have_damaged_eye) tohit-=25;
  63.  
  64.   if (target_is_lying) tohit+=40;
  65.  
  66.   if (CONDTITION) { // not fully known, but obviously involves checking if something is player
  67.     if (combat_difficulty == wimpy) tohit+=20;
  68.     if (combat_difficulty == rough) tohit-=20;
  69.   }
  70.  
  71.   if (tohit > 95) tohit = 95;
  72.  
  73.   return tohit;
  74. }
  75.  
  76. int apply_distance_modifier() {
  77.   attack_is_ranged = 1;
  78.  
  79.   if (weapon_perk == long_range) distmod1 = 4;
  80.     else if (weapon_perk == scope_range) {distmod1 = 5; distmod2 = 8; }
  81.       else distmod1 = 2;
  82.  
  83.   perception = attacker_perception;
  84.  
  85.   if (target_invalid) dist = 0;
  86.     else dist = distance_between_attacker_and_target; // this is distance between central hexes, -1 when attacker is multihex, -1 when target is multihex
  87.  
  88.   if (dist < distmod2) dist+=distmod2; // this happens when target is within minimum range of an scoped range weapon
  89.   else {
  90.     if (attacker_is_player) dist-=(perception-2)*distmod1; // player nerfed
  91.       else dist-=perception*distmod1;
  92.   }
  93.  
  94.   if (-2*perception > dist) dist = -2*perception;
  95.  
  96.   if (attacker_is_player) dist-=2*player_sharpshooter_level;
  97.  
  98.   if (dist >= 0) { if (attacker_eye_damage) dist*=-12; else dist*=-4;}
  99.   else dist*=-4;
  100.  
  101.   if (!(attack_with_norange_argument && (dist<=0))) tohit+=dist;
  102.  
  103.   // technically, here should be dist=0; and from now on, dist will be used as accumulator
  104.  
  105.   if (!target_invalid && !attack_with_norange_argument) tohit-=10*objects_between_attacker_and_target;
  106.     // it's not known which objects are taken into account; probably it has something to do with ShootThru proto flags
  107.     // EDIT: probably it's just a critter counter, however strange results were measured when they were multihex
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement