 # FO2 To-Hit Calculation

Jul 13th, 2017
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
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.
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. }