Duck and Cover Forum Index


Use these links, buy stuff from Amazon and help us out, nubs.
Amazon.com | Amazon.ca | Amazon.co.uk | Amazon.de
  Duck and Cover  •  FAQ  •  Search  •  Memberlist  •  Usergroups   •  Register  •  Profile  •  Log in to check your private messages  •  Log in

 Support DAC!
 I made an important Fallout 2 mod, quick Pooper newspost thi View next topic
View previous topic
Post new topicReply to topic
Author Message
Jim the Dinosaur
Wanderer
Wanderer


Joined: 06 Aug 2005
Posts: 430

PostPosted: Sat May 11, 2013 3:02 pm Reply with quoteBack to top

DOWNLOAD VERSION 0.43

You can download it here along with the Supply and Demand mod.

INSTRUCTIONS

The only requirement for this to work is that you have sfall.

To install you can make a folder titled Patch000.dat in the game directory, use Dat Explorer or another program to extract the original Patch000.dat file in that directory, then put the .int files in the scripts folder. If you don't want to override the dude_obj script, you can just copy the couple of lines at the top of map_enter_p_proc, combat_p_proc and critter_p_proc to your own obj_dude script.

INTRODUCTION

Everybody knows that Fallout is a horribly unbalanced game. The majority of perks, traits and skills are completely useless, and combat invariably goes from being a nailbitingly tense experience early on in a game to a boring untactical eye-critting slaughterfest by the end. This mod tries to address the latter problem by making the late game as tense as the early game. For the moment, the mod only does the chance to hit calculation and the weapon-related Action Point cost calculations for the game, though an extremely unrealistic end project of mine would entail doing all the relevant combat calculations (so also damage and the after hit roll stuff) via hookscripts.

Now, first off, why start out with chance to hit and not, say, the damage model to fix combat? This is because I'm convinced that the root of the balancing problem lies in the fact that whereas the chance to hit system works quite well in the beginning (e.g. if I have an 80% chance of hitting someone with an unaimed shot, then I have a 20% chance of hitting them in the eyes), it quickly veers off the tracks towards the end (e.g. if you're skilled enough, which you will be by mid-game, then an unaimed shot and an eye shot will invariably both end up as 95% hits). While fixing balance is my primary concern, I've also tried to address what are in my view unlogical (e.g. sniping) or boring (e.g. unarmed combat) aspects of the current combat system. I'll now start explaining all the new calculations and the reasoning behind them. The calculations proceed in three phases (two for melee and unarmed), and I'll deal with them one by one. After that I'll explain the changes to the AP cost system. And finally there'll be the scripts themselves for you to check out between spoiler tags.

TO HIT CHANCE FIRST STAGE

Unarmed and Melee Combat

The current system works like this:

Code:
old:(unarmed skill attacker)-(AC target)


This is how it changes in the mod:

Code:
new:(has_skill(attacker, SKILL_UNARMED_COMBAT))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-cripplepen-bodypen-attackerexhaustion-(has_skill(attacker, SKILL_UNARMED_COMBAT)-100)-(get_critter_stat(target, STAT_ag)*agilitymod)-(get_critter_stat(target, STAT_pe))


Okay, probably looks like gibberish, but I'll do my best to explain every element of the calculation.

First, there's of course the unarmed skill of the attacker.

Next, the exhaustion of the target is added. Once the number of turns has exceeded the target's endurance (so after the first turn if your endurance is 1, after the tenth turn if it is 10), a potential 6 point bonus is added to your chance to hit for each consecutive turn, half of which is determined by the ratio of weight carried to maximum weight (that is to say, if you are lightly packed, the effects of exhaustion will be less severe). The same principle however also applies to the attacker's exhaustion, which results in a penalty to hit.

Checks are made for whether the attacker or the target have the Kamikaze trait. In the original, this trait was rarely useful; you sacrificed armor class in favor of a possible extra early turn. I've made the Kamikaze trait into what I originally expected it to be: sacrificing defense for offense. So, what the trait does now is add an agility*3 bonus to to hit and a agility*3 bonus to the opponent's to hit, on top of the old sequence bonus. Will probably have to be changed around a bit still, but I like the principle.

The One Hander trait is somewhat nerfed from the original: 10% bonus for one handed weapons, 20% penalty for two handed weapons.

Being crippled in one arm affects your accuracy by 50% if the weapon is in the relevant arm (or if you are carrying a two handed weapon). Being blind not only gives another 50% penalty, but also an additional gross distance modifier penalty (4 per hex).

The basic bodypart penalty is only slightly changed from the original. Now, the unaimed shot is what I originally imagined it to be: a snapshot. So it's faster than a precision strike, but often also less precise. This means that for melee/unarmed, an unaimed shot has a -20 basic penalty to hit, while for ranged combat it has a -10 basic penalty on top of a -1 per hex distance penalty. So now there's finally a reason to do an aimed blow to the body.

The opponent's unarmed and melee skill now also factors into the calculation. Where in the original system you would eventually always just slug it out, with each blow safely landing, now a superior pugilist will be able to dodge your blows. If the target is carrying a ranged weapon then the attacker gets a 20 point bonus.

Instead of Armor Class, which is now an entirely redundant stat (for more on that see one of the later posts in this thread), agility itself plays a large role. For now the agility bonus gets calculated as follows. As long as the target is not wearing hindering armor (starting with Metal Armor), the penalty is the target's agility*2, which becomes *4 with the dodger perk and even *7 with the hthevade perk on top (if you're not wielding a weapon at the moment that is ofcourse). Once the target is hindered by being armored (this also applies to critters such as Super Mutants), or heavily armored (starting with Power Armor), these penalties drop significantly (e.g. with Power Armor, the target's agility and dodge perk advantages dissappear and only a third of the hth evade perk still applies).

Finally, the target's perception also plays a (minor) roll, as it determines how well the target can anticipate attacker's blows.

Ranged Combat

Here's how the mod calculates ranged combat:
Code:
new:(has_skill(attacker, SKILL_SMALL_GUNS))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-attackerexhaustion-(get_critter_stat(target, STAT_ag)*agilitymod)+(get_critter_stat(attacker, STAT_pe)) - (strengthpen)


A lot of it is similar to the unarmed/melee system, except that the opponent's skill plays no role, that not the target's perception is used for a penalty, but the attacker's perception for a mild bonus and that the strength penalty now applies. The minimum strength was a bit arbitrary in the original (a gatling laser as heavy as a tommy gun, really?) and is now calculated in this way:

Code:
minstrength:=(weaponweight/4)+recoil-((has_trait(TRAIT_PERK, attacker, PERK_weapon_handling_perk) > 0)*3);


So it's basically a combination of the weapon's weight and its "recoil", which I just used a heavy/medium/light weapon scheme for. The result is that a minigun now has a minimum strength of 10, instead of the original 7, which seems reasonable (perhaps still even a bit too optimistic). Here's the resulting penalty, which is calculated on the basis of the amount the attacker is below the minimum strength and how exhausted he is:

Code:
strengthpen:=((minstrength)-(get_critter_stat(attacker, STAT_st)))* (4+(exhaustion/4));


The first stage of thrown weapons is identical to that of other weapons.

TO HIT CHANCE SECOND STAGE (RANGED ONLY)

The basics of determining distance modifiers are as follows:

Code:
(hexes)*((10+lightmod)-perceptionmod);


The basic principle is that the further away the target is, the faster the modifier rises (so that with a 10mm pistol the first 5 hexes have a penalty of 10-perception per hex, the next hexes a penalty of 11-perception, and so on). This process slows down when the weapon's range increases. The perception value for determining range is changed by one with the sharpshooter perk. With a scoped rifle, the distance modifier stays at 10-perception for every distance, but only when aiming. So if you have a perception of 10, and you're aiming a sniper rifle with the sharpshooter perk, the target actually becomes easierto hit the farther he's away, which I think finally makes an explicit sniper character an interesting option. Conversely, taking an unaimed snapshot now gives you an additional one point distance penalty.

The way light affects distance modifiers is that high light levels yield no penalty, medium one point, and low ones two points. What I have now is that, on top of their light adjustments, the night vision perk and the fn fal with nightsight now reduce the penalty by one. Hopefully this makes them a bit less useless.

Throwing weapons work more or less the same way as other ranged weapons, except that the distance modifier is not just impacted by perception, but agility as well. Also, the heave-ho perk is now also a throwing variant of the sharpshooter perk in that it gives a 2 point bonus to distance modifiers (might be a bit too big, but I don't know terribly much about the throwing skill to be honest).

As a side note, you now also get a slight penalty when using a melee weapon over two hexes; not sure if this was the case already.

TO HIT CHANCE THIRD PHASE

To further balance things out, the to hit chance that rolls out of the previous two phases is finally adjusted further based on the bodypart aimed at. This is done in a way akin to the skill progression system: progress becomes gradually more costly. The consequence is that, in addition to the basic penalty, the chance to hit the eyes progresses slower than the chance to hit the body (in the former it's the case that getting to 20% chance progresses normally, then to 40% the "cost" becomes two points per increase, then up to 60% three points, etc. while for the body it's simply the first 50% regular and the next double cost).

I could try to give a complicated rationale for this, but the main reason is balancing. The point of the system is that early combat stays more or less as difficult as it is, while crazy late-game eye-crit rampages stop. To even get above 75% for an eye hit you need to think in the range of a 250+ investment in the related (ranged) combat stat. Some might think this system sacrifices realism for the sake of balance, perhaps pointing out that a skilled marksman can easily reach 80+% hits on eyes during target practice. To that I'd just say I believe combat in Fallout should be thought of as much more dynamic than it looks through the trappings of turn-based combat; what seems like a stationary target in the middle of a dirt road is best thought of as actually someone maneuvering at speed from cover to cover (hence the emphasis on agility, endurance and perception in my system); try getting 80% eye-hits on a dynamic target like that.

Finally, the attacker gets a further 40% bonus if the target is lying down, just like in the original.

CHANGES TO AP COST

I've always felt the AP costs of the various weapons in Fallout were often extremely arbitrary (e.g. why is a .44 magnum faster to shoot than a 10 MM pistol?).

With my own approach, I've tried to keep things as simple and unarbitrary as possible. The base AP cost for an unaimed snapshot (remember that this now has a penalty, making the aimed bodyshot the new "safe" option) is now 3 points (the exception is 4 points for thrown), to which points are added for two handed weapons (1), for energy weapons (1), for big guns (2), for aimed shots (2, or 3 if with a scoped weapon), and for bursts as a secondary mode (2). The consequence is that whereas for instance the Minigun stays the same AP (3+1+2=6), the super sledge now costs 4 for the primary attack (3+1=4). Of course the old exceptions (like flares costing 1 AP) still apply. Unarmed has stayed the same as in the original, except that I've incorporated Magnus's common sense fix of making the secondary attacks cost only one additional AP. Having crippled arms also raises the AP cost, though only if the weapon is in the relevant arm or if you're using a two-handed weapon.

Of the AP-related perks and traits I needed to change at least one, given that I've already lowered the base cost for ranged weapons
from 4 to 3. I decided to make the fast shot trait something which makes you better at fast shots, so that the basic 10% penalty for snapshots now dissappears (the ranged penalty still applies however). The increased rate of fire/hth attacks perks still reduce the relevant AP costs, though (given that they are so incredibly overpowered at the moment), they also come with a base penalty of 10% to hit now. These perks are still huge advantages all the same of course.

SCRIPTS

The to hit script:

Spoiler: (highlight with mouse to read)
Code:


//hs_tohit.int
procedure start;

#include "C:\Program Files (x86)\GOG.com\Fallout 2 Mapper\scripts\HEADERS\sfall.h"
#include "C:\Program Files (x86)\GOG.com\Fallout 2 Mapper\scripts\HEADERS\define.h"
#include "C:\Program Files (x86)\GOG.com\Fallout 2 Mapper\scripts\HEADERS\command.h"

procedure start begin
   variable hitchance;
   variable target;
   variable attacker;
   variable bodypart;
   variable weaponright;
   variable weaponleft;
   variable weaponrange;
   variable weaponweight;
   variable cripplepen;
   variable hexes;
   variable x;
   variable perceptionmod;
   variable snapshotpen;
   variable bodypen;
   variable onehander;
   variable attackerkamikaze;
   variable targetkamikaze;
   variable agilitymod;
   variable tmp;
   variable tmphitchance;
   variable tmphitchance2;
   variable tmphitchance3;
   variable tmphitchancemod;
   variable attackerexhaustion;
   variable targetexhaustion;
   variable minstrength;
   variable strengthpen;
   variable recoil;
   variable hthevade;
   variable lightmod;
   
   if(init_hook) then begin

   end else begin
         hitchance:=get_sfall_arg;
         attacker:=get_sfall_arg;
         target:=get_sfall_arg;
        bodypart:=get_sfall_arg;
       hexes:=tile_distance_objs(target, attacker);
       if weapon_in_right_hand(attacker) and not (two_handed_in_right_hand(attacker)) then begin
       cripplepen:=((critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT)*50)+((critter_state(dude_obj) bwand DAM_BLIND)*50);
       end else if weapon_in_left_hand(attacker) and not (two_handed_in_left_hand(attacker)) then begin
       cripplepen:=((critter_state(dude_obj) bwand DAM_CRIP_ARM_LEFT)*50)+((critter_state(dude_obj) bwand DAM_BLIND)*50);
       end else begin
       cripplepen:=((critter_state(dude_obj) bwand DAM_CRIP_ARM_LEFT)*50)+((critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT)*50)+((critter_state(dude_obj) bwand DAM_BLIND)*50);
      end if get_sfall_global_int("combattu") > get_critter_stat(target, STAT_en) then begin
      targetexhaustion:=((get_sfall_global_int("combattu") - get_critter_stat(target, STAT_en))*(3+(3*(get_critter_stat(target, STAT_carry_amt)/who_carry_amount(target)))));
      end else begin
      targetexhaustion:=0;
      end if (get_sfall_global_int("combattu")) > (get_critter_stat(attacker, STAT_en)) then begin
      attackerexhaustion:=((get_sfall_global_int("combattu") - get_critter_stat(attacker, STAT_en))*(3+(3*(get_critter_stat(attacker, STAT_carry_amt)/who_carry_amount(attacker)))));
      end else begin
      attackerexhaustion:=0;
      end
      hthevade:=(has_trait(TRAIT_PERK, target, PERK_hth_evade_perk) > 0)*((not weapon_in_left_hand(target) and not weapon_in_right_hand(target))*(1 + (get_critter_stat(attacker, STAT_dmg_thresh) ^ 4) + (get_critter_stat(attacker, STAT_dmg_thresh) ^ 12)));
      if (two_handed_in_left_hand(attacker) or two_handed_in_right_hand(attacker)) and (has_trait(TRAIT_TRAIT, attacker, TRAIT_one_hander) > 0) then begin
         onehander:=-20;
      end else if (not(two_handed_in_left_hand(attacker) or two_handed_in_right_hand(attacker))) and (has_trait(TRAIT_TRAIT, attacker, TRAIT_one_hander) > 0) then begin
         onehander:=10;
      end else begin
         onehander:=0;
      end
      if (ranged_in_left_hand(attacker) or ranged_in_right_hand(attacker)) then begin
         if (bodypart==1) or (bodypart==2) or (bodypart==7) then begin
            tmp := 35;
            bodypen := 30 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_rate_of_fire) > 0)*10);
            snapshotpen := 0;
         end else if (bodypart==8) then begin
            tmp := 35;
            bodypen := 10 - ((has_trait(TRAIT_TRAIT, attacker, TRAIT_fast_shot) > 0)*10) + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_rate_of_fire) > 0)*10);
            snapshotpen := 1;
         end else if (bodypart==4) or (bodypart==5) then begin
            tmp := 40;
            bodypen := 20 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_rate_of_fire) > 0)*10);
            snapshotpen := 0;
         end else if (bodypart==0) then begin
            tmp := 30;
            bodypen := 40 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_rate_of_fire) > 0)*10);
            snapshotpen := 0;
         end else if (bodypart==3) then begin
            tmp := 50;
            bodypen := 0 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_rate_of_fire) > 0)*10);
            snapshotpen := 0;
         end else if (bodypart==6) then begin
            tmp := 20;
            bodypen := 60 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_rate_of_fire) > 0)*10);
            snapshotpen := 0;
         end
      end
      else if (thrown_in_left_hand(attacker) or thrown_in_right_hand(attacker)) then begin
         if (bodypart==1) or (bodypart==2) or (bodypart==7) then begin
            tmp := 35;
            bodypen := 30;
            snapshotpen := 0;
         end else if (bodypart==8) then begin
            tmp := 35;
            bodypen := 10;
            snapshotpen := 1;
         end else if (bodypart==4) or (bodypart==5) then begin
            tmp := 40;
            bodypen := 20;
            snapshotpen := 0;
         end else if (bodypart==0) then begin
            tmp := 30;
            bodypen := 40;
            snapshotpen := 0;
         end else if (bodypart==3) then begin
            tmp := 50;
            bodypen := 0;
            snapshotpen := 0;
         end else if (bodypart==6) then begin
            tmp := 20;
            bodypen := 60;
            snapshotpen := 0;
         end
      end
      else begin
         if (bodypart==1) or (bodypart==2) or (bodypart==7) then begin
            tmp := 35;
            bodypen := 30 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_hth_attacks) > 0)*10);
            snapshotpen := 0;
         end else if (bodypart==8) then begin
            tmp := 35;
            bodypen := 20 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_hth_attacks) > 0)*10);
            snapshotpen := 1;
         end else if (bodypart==4) or (bodypart==5) then begin
            tmp := 40;
            bodypen := 20 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_hth_attacks) > 0)*10);
            snapshotpen := 0;
         end else if (bodypart==0) then begin
            tmp := 30;
            bodypen := 40 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_hth_attacks) > 0)*10);
            snapshotpen := 0;
         end else if (bodypart==3) then begin
            tmp := 50;
            bodypen := 0 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_hth_attacks) > 0)*10);
            snapshotpen := 0;
         end else if (bodypart==6) then begin
            tmp := 20;
            bodypen := 60 + ((has_trait(TRAIT_PERK, attacker, PERK_bonus_hth_attacks) > 0)*10);
            snapshotpen := 0;
         end
      end
      if (thrown_in_left_hand(attacker) or thrown_in_right_hand(attacker) or melee_in_left_hand(attacker) or melee_in_right_hand(attacker)) then begin
      perceptionmod:=((get_critter_stat(attacker, STAT_pe)+get_critter_stat(attacker, STAT_ag))/2)+((has_trait(TRAIT_PERK, attacker, PERK_heave_ho) > 0)*2) - ((critter_state(dude_obj) bwand DAM_BLIND)*4);
      end else if (ranged_in_left_hand(attacker) or ranged_in_right_hand(attacker)) then begin
      perceptionmod:=get_critter_stat(attacker, STAT_pe) + (has_trait(TRAIT_PERK, attacker, PERK_sharpshooter) > 0) - snapshotpen - ((critter_state(dude_obj) bwand DAM_BLIND)*4);
      end
      agilitymod:=(get_critter_stat(attacker, STAT_dmg_thresh) ^ 4) + (get_critter_stat(attacker, STAT_dmg_thresh) ^ 12) + ((has_trait(TRAIT_PERK, target, PERK_dodger) > 0)*((get_critter_stat(attacker, STAT_dmg_thresh) ^ 4) + (get_critter_stat(attacker, STAT_dmg_thresh) ^ 12))) + (hthevade);
      attackerkamikaze:=(has_trait(TRAIT_TRAIT, attacker, TRAIT_kamikaze) > 0)*(get_critter_stat(attacker, STAT_ag)*2);
      targetkamikaze:=(has_trait(TRAIT_TRAIT, target, TRAIT_kamikaze) > 0)*(get_critter_stat(target, STAT_ag)*3);
      weaponleft:=obj_pid(critter_inven_obj(attacker,INVEN_TYPE_LEFT_HAND));
      weaponright:=obj_pid(critter_inven_obj(attacker,INVEN_TYPE_RIGHT_HAND));
      if weaponleft != -1 then begin
         weaponrange:=pid_range(weaponleft);
         weaponweight:=pid_weight(weaponleft);
      end else if weaponright != -1 then begin
         weaponrange:=pid_range(weaponright);
         weaponweight:=pid_weight(weaponright);
      end else begin
         weaponrange:=0;
         weaponweight:=0;
      end
      if heavy_weapon_left_hand(attacker) or heavy_weapon_right_hand(attacker) then begin
         recoil:=3;
      end else if medium_weapon_left_hand(attacker) or medium_weapon_right_hand(attacker) then begin
         recoil:=3;
      end else if light_weapon_left_hand(attacker) or light_weapon_right_hand(attacker) then begin
         recoil:=2;
      end
      minstrength:=(weaponweight/4)+recoil-((has_trait(TRAIT_PERK, attacker, PERK_weapon_handling_perk) > 0)*3);
      if minstrength > (get_critter_stat(attacker, STAT_st)) then begin
         strengthpen:=((minstrength)-(get_critter_stat(attacker, STAT_st)))*(4+(attackerexhaustion/4));
      end else begin
         strengthpen:=0;
      end if (get_light_level ^ 30000) and not ((obj_pid(critter_inven_obj(attacker,INVEN_TYPE_LEFT_HAND)) == PID_FN_FAL_NIGHT_SCOPE) or (obj_pid(critter_inven_obj(attacker,INVEN_TYPE_RIGHT_HAND)) == PID_FN_FAL_NIGHT_SCOPE) or (has_trait(TRAIT_PERK, attacker, PERK_night_vision) > 0)) then begin
         lightmod:=2;
      end else if ((get_light_level ^ 30000) and ((obj_pid(critter_inven_obj(attacker,INVEN_TYPE_LEFT_HAND)) == PID_FN_FAL_NIGHT_SCOPE) or (obj_pid(critter_inven_obj(attacker,INVEN_TYPE_RIGHT_HAND)) == PID_FN_FAL_NIGHT_SCOPE) or (has_trait(TRAIT_PERK, attacker, PERK_night_vision) > 0))) or (get_light_level ^ 45000) then begin
         lightmod:=1;
      end else begin
         lightmod:=0;
      end if (ranged_in_left_hand(attacker) or ranged_in_right_hand(attacker) or thrown_in_left_hand(attacker) or thrown_in_right_hand(attacker)) then begin
          x:=(weaponrange/5);
       end else begin
          x:=3;
      end if not ((weapon_in_left_hand(attacker)) or (weapon_in_right_hand(attacker))) then begin
            if not (weapon_in_left_hand(target) or weapon_in_right_hand(target)) then begin
               tmphitchance:=(has_skill(attacker, SKILL_UNARMED_COMBAT))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-cripplepen-attackerexhaustion-(has_skill(attacker, SKILL_UNARMED_COMBAT)-100)-(get_critter_stat(target, STAT_ag)*agilitymod)-(get_critter_stat(target, STAT_pe));
            end else if (melee_in_left_hand(target) or melee_in_right_hand(target)) then begin
               tmphitchance:=(has_skill(attacker, SKILL_UNARMED_COMBAT))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-cripplepen-attackerexhaustion-(has_skill(attacker, SKILL_MELEE)-100)-(get_critter_stat(target, STAT_ag)*agilitymod)-(get_critter_stat(target, STAT_pe));
            end else begin
               tmphitchance:=(has_skill(attacker, SKILL_UNARMED_COMBAT))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-cripplepen-attackerexhaustion-(has_skill(attacker, SKILL_MELEE)-120)-(get_critter_stat(target, STAT_ag)*agilitymod)-(get_critter_stat(target, STAT_pe));
         end
      end else if (melee_in_left_hand(attacker) or melee_in_right_hand(attacker)) then begin
            if not (weapon_in_left_hand(target) or weapon_in_right_hand(target)) then begin
               tmphitchance:=(has_skill(attacker, SKILL_MELEE))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-cripplepen-attackerexhaustion-(has_skill(attacker, SKILL_UNARMED_COMBAT)-100)-(get_critter_stat(target, STAT_ag)*agilitymod)-(get_critter_stat(target, STAT_pe)) - (strengthpen);
            end else if (melee_in_left_hand(target) or melee_in_right_hand(target)) then begin
               tmphitchance:=(has_skill(attacker, SKILL_MELEE))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-cripplepen-attackerexhaustion-(has_skill(attacker, SKILL_MELEE)-100)-(get_critter_stat(target, STAT_ag)*agilitymod)-(get_critter_stat(target, STAT_pe)) - (strengthpen);
            end else begin
               tmphitchance:=(has_skill(attacker, SKILL_MELEE))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-cripplepen-attackerexhaustion-(has_skill(attacker, SKILL_MELEE)-120)-(get_critter_stat(target, STAT_ag)*agilitymod)-(get_critter_stat(target, STAT_pe)) - (strengthpen);
         end
      end   else if (small_arms_in_left_hand(attacker) or small_arms_in_right_hand(attacker)) then begin
         tmphitchance:=(has_skill(attacker, SKILL_SMALL_GUNS))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-cripplepen-attackerexhaustion-(get_critter_stat(target, STAT_ag)*agilitymod)+(get_critter_stat(attacker, STAT_pe)) - (strengthpen);
      end else if (energy_weapon_in_left_hand(attacker) or energy_weapon_in_right_hand(attacker)) then begin
         tmphitchance:=(has_skill(attacker, SKILL_ENERGY_WEAPONS))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-cripplepen-attackerexhaustion-(get_critter_stat(target, STAT_ag)*agilitymod)+(get_critter_stat(attacker, STAT_pe)) - (strengthpen);
      end else if (big_gun_in_left_hand(attacker) or big_gun_in_right_hand(attacker)) then begin
         tmphitchance:=(has_skill(attacker, SKILL_BIG_GUNS))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-cripplepen-attackerexhaustion-(get_critter_stat(target, STAT_ag)*agilitymod)+(get_critter_stat(attacker, STAT_pe)) - (strengthpen);
      end else if (thrown_in_left_hand(attacker) or thrown_in_right_hand(attacker)) then begin
         tmphitchance:=(has_skill(attacker, SKILL_THROWING))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-cripplepen-attackerexhaustion-(get_critter_stat(target, STAT_ag)*agilitymod)+(get_critter_stat(attacker, STAT_pe)) - (strengthpen);
      end
         if ((weapon_in_left_hand(attacker) or weapon_in_right_hand(attacker)) and not ((scoped_rifle_in_left_hand(attacker) or scoped_rifle_in_right_hand(attacker)) and (bodypart != 8))) then begin
           if (hexes>1) and (hexes^=x) then begin
               tmphitchancemod:=(hexes)*((10+lightmod)-perceptionmod);
           end else if (hexes>(x)) and (hexes^=x*2) then begin
                 tmphitchancemod:=((hexes-x)*((11+lightmod)-perceptionmod))+(x*((10+lightmod)-perceptionmod));
            end else if (hexes>(x*2)) and (hexes^=x*3) then begin
                 tmphitchancemod:=((hexes-(x*2))*((12+lightmod)-perceptionmod))+(x*((10+lightmod)-perceptionmod))+(x*((11+lightmod)-perceptionmod));
              end else if (hexes>(x*3)) and (hexes^=x*4) then begin
                 tmphitchancemod:=((hexes-(x*3))*((13+lightmod)-perceptionmod))+(x*((10+lightmod)-perceptionmod))+(x*((11+lightmod)-perceptionmod))+(x*((12+lightmod)-perceptionmod));
            end else if (hexes>(x*4)) then begin
                 tmphitchancemod:=((hexes-(x*4))*((14+lightmod)-perceptionmod))+(x*((10+lightmod)-perceptionmod))+(x*((11+lightmod)-perceptionmod))+(x*((12+lightmod)-perceptionmod))+(x*((13+lightmod)-perceptionmod));
            end else begin
               tmphitchancemod:=0;
            end
         end else if (scoped_rifle_in_left_hand(attacker) or scoped_rifle_in_right_hand(attacker)) and (bodypart != 8) then begin
            tmphitchancemod:=hexes*((10+lightmod)-perceptionmod);
         end else begin
            tmphitchancemod:=0;
         end
      tmphitchance2:=tmphitchance-tmphitchancemod;
        if (tmphitchance2>(tmp*28)) then begin
           tmphitchance3:=((tmphitchance2-(tmp*28))/8 + (tmp*7));
        end else if (tmphitchance2>(tmp*21)) then begin
           tmphitchance3:=((tmphitchance2-(tmp*21))/7 + (tmp*6));
        end else if (tmphitchance2>(tmp*15)) then begin
           tmphitchance3:=((tmphitchance2-(tmp*15))/6 + (tmp*5));
        end else if (tmphitchance2>(tmp*10)) then begin
           tmphitchance3:=((tmphitchance2-(tmp*10))/5 + (tmp*4));
        end else if (tmphitchance2>(tmp*6)) then begin
           tmphitchance3:=((tmphitchance2-(tmp*6))/4 + (tmp*3));
        end else if (tmphitchance2>(tmp*3)) then begin
           tmphitchance3:=((tmphitchance2-(tmp*3))/3 + (tmp*2));
        end else if (tmphitchance2>(tmp)) then begin
           tmphitchance3:=((tmphitchance2-tmp)/2 + tmp);
        end else begin
           tmphitchance3:=tmphitchance2;
        end
        if is_critter_prone(target) then begin
           tmphitchance3+=40;
        end if tmphitchance3 > 95 then begin
          hitchance:=95;
       end else begin
           hitchance:=tmphitchance3;
        end
       //display_msg(" weaponleft " + weaponleft);
         //display_msg(" weaponright " + weaponright);
       //display_msg(" weaponrange " + weaponrange);
       //display_msg(" weaponweight " + weaponweight);
       //display_msg(" hexes " + hexes);
       //display_msg(" x " + x);
       //display_msg(" perceptionmod " + perceptionmod);
       //display_msg(" agilitymod " + agilitymod);
       //display_msg(" tmp " + tmp);
       //display_msg(" tmphitchance " + tmphitchance);
       //display_msg(" tmphitchance2 " + tmphitchance2);
       //display_msg(" tmphitchance3 " + tmphitchance3);
       //display_msg(" tmphitchancemod " + tmphitchancemod);
       //display_msg(" onehander " + onehander);
       //display_msg(" snapshotpen " + snapshotpen);
       //display_msg(" attackerexhaustion " + attackerexhaustion);
       //display_msg(" bodypen " + bodypen);
       //display_msg(" targetexhaustion " + targetexhaustion);
       //display_msg(" attackerkamikaze " + attackerkamikaze);
       //display_msg(" targetkamikaze " + targetkamikaze);
       //display_msg(" minstrength " + minstrength);
       //display_msg(" strengthpen " + strengthpen);
       //display_msg(" recoil " + recoil);
       //display_msg(" hthevade " + hthevade);
       //display_msg(" lightmod " + lightmod);
       //display_msg(" prone " + is_critter_prone(target));
       //display_msg(" cripplepen " + cripplepen);
       //display_msg(" skill self " + has_skill(attacker, SKILL_UNARMED_COMBAT));
       //display_msg(" skill opponent " + has_skill(target, SKILL_UNARMED_COMBAT));
            set_sfall_return(hitchance);
   end
end 


The AP cost script:

Spoiler: (highlight with mouse to read)
Code:
procedure start;
#include "C:\Program Files (x86)\GOG.com\Fallout 2 Mapper\scripts\HEADERS\sfall.h"
#include "C:\Program Files (x86)\GOG.com\Fallout 2 Mapper\scripts\HEADERS\define.h"

procedure start begin
  variable attacker, type, aimed, i;
  if not init_hook then begin
    attacker:=get_sfall_arg;
    type:=get_sfall_arg;
    aimed:=get_sfall_arg;
    i:=-1;
    if (type == ATKTYPE_LWEP1) or (type == ATKTYPE_LWEP2) then begin
       if (ranged_in_left_hand(attacker)) then begin
            i:= 3 + (two_handed_in_left_hand(attacker)) + (ranged_six_ap_left_hand(attacker)) + (small_energy_in_left_hand(attacker)) + (big_gun_in_left_hand(attacker) or big_energy_in_left_hand(attacker)) - (has_trait(TRAIT_PERK, attacker, PERK_bonus_rate_of_fire) > 0) + (((critter_state(dude_obj) bwand DAM_CRIP_ARM_LEFT) or ((critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT) and two_handed_in_left_hand(attacker)))*2);
       end else if (thrown_in_left_hand(attacker)) then begin
          i:= 3 + ((critter_state(dude_obj) bwand DAM_CRIP_ARM_LEFT)*2) - (((obj_pid(critter_inven_obj(attacker,INVEN_TYPE_LEFT_HAND)) == PID_ACTIVE_FLARE) or (obj_pid(critter_inven_obj(attacker,INVEN_TYPE_LEFT_HAND)) == PID_FLARE))*2);
       end else if (melee_in_left_hand(attacker) or fist_enhanced_in_left_hand(attacker)) then begin
          i:= 3 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0) + (two_handed_in_left_hand(attacker)) + (((critter_state(dude_obj) bwand DAM_CRIP_ARM_LEFT) or ((critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT) and two_handed_in_left_hand(attacker)))*2) + (obj_pid(critter_inven_obj(attacker,INVEN_TYPE_LEFT_HAND)) == PID_MEGA_POWER_FIST);
       end
    end else if (type == ATKTYPE_RWEP1) or (type == ATKTYPE_RWEP2) then begin
       if (ranged_in_right_hand(attacker)) then begin
            i:= 3 + (two_handed_in_right_hand(attacker)) + (small_energy_in_right_hand(attacker)) + (big_gun_in_right_hand(attacker) or big_energy_in_right_hand(attacker)) + (ranged_six_ap_right_hand(attacker)) - (has_trait(TRAIT_PERK, attacker, PERK_bonus_rate_of_fire) > 0) + (((critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT) or ((critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT) and two_handed_in_right_hand(attacker)))*2);
       end else if (thrown_in_right_hand(attacker)) then begin
          i:= 3 + ((critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT)*2) - (((obj_pid(critter_inven_obj(attacker,INVEN_TYPE_RIGHT_HAND)) == PID_ACTIVE_FLARE) or (obj_pid(critter_inven_obj(attacker,INVEN_TYPE_RIGHT_HAND)) == PID_FLARE))*2);
       end else if (melee_in_right_hand(attacker) or fist_enhanced_in_right_hand(attacker)) then begin
          i:= 3 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0) + (two_handed_in_right_hand(attacker)) + (((critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT) or ((critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT) and two_handed_in_right_hand(attacker)))*2) + (obj_pid(critter_inven_obj(attacker,INVEN_TYPE_RIGHT_HAND)) == PID_MEGA_POWER_FIST);
       end
    end else if (type == ATKTYPE_PUNCH) or (type == ATKTYPE_STRONGPUNCH) or (type == ATKTYPE_HAMMERPUNCH) or (type == ATKTYPE_HAYMAKER) then begin
         i:= 3 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0) + (critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT) + (critter_state(dude_obj) bwand DAM_CRIP_ARM_LEFT);
    end else if (type == ATKTYPE_STRONGKICK) or (type == ATKTYPE_SNAPKICK) or (type == ATKTYPE_POWERKICK) or (type == ATKTYPE_KICK) then begin
         i:= 4 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0) + (critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT) + (critter_state(dude_obj) bwand DAM_CRIP_ARM_LEFT);
    end else if (type == ATKTYPE_PALMSTRIKE) or (type == ATKTYPE_PIERCINGSTRIKE) or (type == ATKTYPE_JAB) then begin
         i:= 4 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0) + (critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT) + (critter_state(dude_obj) bwand DAM_CRIP_ARM_LEFT);
    end else if (type == ATKTYPE_HIPKICK) or (type == ATKTYPE_HOOKKICK) or (type == ATKTYPE_PIERCINGKICK) then begin
         i:= 5 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0) + (critter_state(dude_obj) bwand DAM_CRIP_ARM_RIGHT) + (critter_state(dude_obj) bwand DAM_CRIP_ARM_LEFT);
    end if (type == ATKTYPE_LWEP2) or (type == ATKTYPE_RWEP2) then begin
       if (ranged_in_left_hand(attacker) or ranged_in_right_hand(attacker)) then begin
          i+= 2;
      end else if (thrown_in_left_hand(attacker) or thrown_in_right_hand(attacker)) then begin
          i+= 0 - (has_trait(TRAIT_PERK, dude_obj, PERK_bonus_hth_attacks) > 0);
      end else if (light_melee_in_left_hand(attacker) or light_melee_in_right_hand(attacker)) then begin
          i+= 2;
      end else if (heavy_melee_in_left_hand(attacker) or heavy_melee_in_right_hand(attacker)) then begin
          i+= 1;
       end
    end if aimed then begin
       i+=2+(scoped_rifle_in_left_hand(attacker) or scoped_rifle_in_right_hand(attacker))+(has_trait(TRAIT_TRAIT, attacker, TRAIT_fast_shot) > 0);
    end if i > 10 then begin
    i := 10;
    end if i != -1 then begin
      set_sfall_return(i);
    end
  end
end
View user's profileSend private message
Redeye
I lied
I lied


Joined: 07 Mar 2005
Posts: 4164
Location: filth

PostPosted: Fri Aug 16, 2013 1:35 am Reply with quoteBack to top

Good work!

Now if I can just be bothered to install FO2 again.
View user's profileSend private message
Jim the Dinosaur
Wanderer
Wanderer


Joined: 06 Aug 2005
Posts: 430

PostPosted: Mon Aug 19, 2013 1:27 am Reply with quoteBack to top

Thanks! But don't download this version. Haven't updated this thread.

DOWNLOAD VERSION 1.0

You can download the mods here.

REQUIREMENTS/COMPATIBILITY

The only requirement for this to work is that you have sfall installed. It is compatible with either the official 1.02 patch, or killap's Unofficial Patch (v. 1.02.28).

INSTALLATION INSTRUCTIONS

To install you need to make a folder titled Patch000.dat in the game directory, and then use Dat Explorer or another program to extract your Patch000.dat file in that directory. Now, if you're using the full install, what you have to do is extract the contents of the relevant (either the regular or the Unofficial Patch compatible) "Full Install" folder in your game folder. If you're installing specific components, then extract them both into your new Patch000.dat's scripts folder and a data/scripts folder as well. All the mods work seperately, though this does mean that there are some duplicate files. Most of these are identical, except for the Morale System, which has unique versions of many files. So, if you're installing it without the morale system, just install whatever you want in whichever order, but if you're using the morale system you have to install that one last (so overwriting all the previous files). One last step (if you want to use the fixed hp changes specifically, or are using a full install), is to add the Stats.ini to the main game folder and go to these lines in sfall's ddraw.ini file:

;To change the relationship between SPECIAL stats and derived stats, uncomment the next line
; See the stats.ini in the modders pack for an example file
;DerivedStats=stats.ini

and uncomment the last line. Now all you should do is write protect the "maps" and "proto" folders in the Patch000.dat folder (right click on the folders and go to the permission options).


CHANGES TO THE TO HIT CHANCE FORMULA

Spoiler: (highlight with mouse to read)
I'm convinced that the root of the balancing problem lies in the fact that whereas the chance to hit system works quite well in the beginning (e.g. if I have an 80% chance of hitting someone with an unaimed shot, then I have a 20% chance of hitting them in the eyes), it quickly veers off the tracks towards the end (e.g. if you're skilled enough, which you will be by mid-game, then an unaimed shot and an eye shot will invariably both end up as 95% hits). While fixing balance is my primary concern, I've also tried to address what are in my view unlogical (e.g. sniping) or boring (e.g. unarmed combat) aspects of the current combat system. I'll now start explaining all the new calculations and the reasoning behind them. The calculations proceed in three phases (two for melee and unarmed), and I'll deal with them one by one.

TO HIT CHANCE FIRST STAGE

Unarmed and Melee Combat

The current system works like this:

Code:
old:(unarmed skill attacker)-(AC target)


This is how it changes in the mod:

Code:
new:(has_skill(attacker, SKILL_UNARMED_COMBAT))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-cripplepen-bodypen-attackerexhaustion-(has_skill(attacker, SKILL_UNARMED_COMBAT)-100)-(get_critter_stat(target, STAT_ag)*agilitymod)-(get_critter_stat(target, STAT_pe))


Okay, probably looks like gibberish, but I'll do my best to explain every element of the calculation.

First, there's of course the unarmed skill of the attacker.

Next, the exhaustion of the target is added. Once the number of turns has exceeded the target's endurance (so after the first turn if your endurance is 1, after the tenth turn if it is 10), a potential 6 point bonus is added to your chance to hit for each consecutive turn, half of which is determined by the ratio of weight carried to maximum weight (that is to say, if you are lightly packed, the effects of exhaustion will be less severe). The same principle however also applies to the attacker's exhaustion, which results in a penalty to hit.

Checks are made for whether the attacker or the target have the Kamikaze trait. In the original, this trait was rarely useful; you sacrificed armor class in favor of a possible extra early turn. I've made the Kamikaze trait into what I originally expected it to be: sacrificing defense for offense. So, what the trait does now is add an agility*3 bonus to to hit and a agility*3 bonus to the opponent's to hit, on top of the old sequence bonus. Will probably have to be changed around a bit still, but I like the principle.

The One Hander trait is somewhat nerfed from the original: 10% bonus for one handed weapons, 20% penalty for two handed weapons.

Being crippled in one arm affects your accuracy by 50% if the weapon is in the relevant arm (or if you are carrying a two handed weapon). Being blind not only gives another 50% penalty, but also an additional gross distance modifier penalty (4 per hex).

The basic bodypart penalty is only slightly changed from the original. Now, the unaimed shot is what I originally imagined it to be: a snapshot. So it's faster than a precision strike, but often also less precise. This means that for melee/unarmed, an unaimed shot has a -20 basic penalty to hit, while for ranged combat it has a -10 basic penalty on top of a -1 per hex distance penalty. So now there's finally a reason to do an aimed blow to the body.

The opponent's unarmed and melee skill now also factors into the calculation. Where in the original system you would eventually always just slug it out, with each blow safely landing, now a superior pugilist will be able to dodge your blows. If the target is carrying a ranged weapon then the attacker gets a 20 point bonus.

Instead of Armor Class, which is now an entirely redundant stat (for more on that see one of the later posts in this thread), agility itself plays a large role. For now the agility bonus gets calculated as follows. As long as the target is not wearing hindering armor (starting with Metal Armor), the penalty is the target's agility*2, which becomes *4 with the dodger perk and even *7 with the hthevade perk on top (if you're not wielding a weapon at the moment that is ofcourse). Once the target is hindered by being armored (this also applies to critters such as Super Mutants), or heavily armored (starting with Power Armor), these penalties drop significantly (e.g. with Power Armor, the target's agility and dodge perk advantages dissappear and only a third of the hth evade perk still applies).

Finally, the target's perception also plays a (minor) roll, as it determines how well the target can anticipate attacker's blows.

Ranged Combat

Here's how the mod calculates ranged combat:
Code:
new:(has_skill(attacker, SKILL_SMALL_GUNS))+targetexhaustion+attackerkamikaze+targetkamikaze+onehander-bodypen-attackerexhaustion-(get_critter_stat(target, STAT_ag)*agilitymod)+(get_critter_stat(attacker, STAT_pe)) - (strengthpen)


A lot of it is similar to the unarmed/melee system, except that the opponent's skill plays no role, that not the target's perception is used for a penalty, but the attacker's perception for a mild bonus and that the strength penalty now applies. The minimum strength was a bit arbitrary in the original (a gatling laser as heavy as a tommy gun, really?) and is now calculated in this way:

Code:
minstrength:=(weaponweight/4)+recoil-((has_trait(TRAIT_PERK, attacker, PERK_weapon_handling_perk) > 0)*3);


So it's basically a combination of the weapon's weight and its "recoil", which I just used a heavy/medium/light weapon scheme for. The result is that a minigun now has a minimum strength of 10, instead of the original 7, which seems reasonable (perhaps still even a bit too optimistic). Here's the resulting penalty, which is calculated on the basis of the amount the attacker is below the minimum strength and how exhausted he is:

Code:
strengthpen:=((minstrength)-(get_critter_stat(attacker, STAT_st)))* (4+(exhaustion/4));


The first stage of thrown weapons is identical to that of other weapons.

TO HIT CHANCE SECOND STAGE (RANGED ONLY)

The basics of determining distance modifiers are as follows:

Code:
(hexes)*((10+lightmod)-perceptionmod);


The basic principle is that the further away the target is, the faster the modifier rises (so that with a 10mm pistol the first 5 hexes have a penalty of 10-perception per hex, the next hexes a penalty of 11-perception, and so on). This process slows down when the weapon's range increases. The perception value for determining range is changed by one with the sharpshooter perk. With a scoped rifle, the distance modifier stays at 10-perception for every distance, but only when aiming. So if you have a perception of 10, and you're aiming a sniper rifle with the sharpshooter perk, the target actually becomes easierto hit the farther he's away, which I think finally makes an explicit sniper character an interesting option. Conversely, taking an unaimed snapshot now gives you an additional one point distance penalty.

The way light affects distance modifiers is that high light levels yield no penalty, medium one point, and low ones two points. What I have now is that, on top of their light adjustments, the night vision perk and the fn fal with nightsight now reduce the penalty by one. Hopefully this makes them a bit less useless.

Throwing weapons work more or less the same way as other ranged weapons, except that the distance modifier is not just impacted by perception, but agility as well. Also, the heave-ho perk is now also a throwing variant of the sharpshooter perk in that it gives a 2 point bonus to distance modifiers (might be a bit too big, but I don't know terribly much about the throwing skill to be honest).

As a side note, you now also get a slight penalty when using a melee weapon over two hexes; not sure if this was the case already.

TO HIT CHANCE THIRD PHASE

To further balance things out, the to hit chance that rolls out of the previous two phases is finally adjusted further based on the bodypart aimed at. This is done in a way akin to the skill progression system: progress becomes gradually more costly. The consequence is that, in addition to the basic penalty, the chance to hit the eyes progresses slower than the chance to hit the body (in the former it's the case that getting to 20% chance progresses normally, then to 40% the "cost" becomes two points per increase, then up to 60% three points, etc. while for the body it's simply the first 50% regular and the next double cost).

I could try to give a complicated rationale for this, but the main reason is balancing. The point of the system is that early combat stays more or less as difficult as it is, while crazy late-game eye-crit rampages stop. To even get above 75% for an eye hit you need to think in the range of a 250+ investment in the related (ranged) combat stat. Some might think this system sacrifices realism for the sake of balance, perhaps pointing out that a skilled marksman can easily reach 80+% hits on eyes during target practice. To that I'd just say I believe combat in Fallout should be thought of as much more dynamic than it looks through the trappings of turn-based combat; what seems like a stationary target in the middle of a dirt road is best thought of as actually someone maneuvering at speed from cover to cover (hence the emphasis on agility, endurance and perception in my system); try getting 80% eye-hits on a dynamic target like that.

Finally, the attacker gets a further 40% bonus if the target is lying down, just like in the original.


CHANGES TO AP COST

Spoiler: (highlight with mouse to read)
I've always felt the AP costs of the various weapons in Fallout were often extremely arbitrary (e.g. why is a .44 magnum faster to shoot than a 10 MM pistol?).

With my own approach, I've tried to keep things as simple and unarbitrary as possible. The base AP cost for an unaimed snapshot (remember that this now has a penalty, making the aimed bodyshot the new "safe" option) is now 3 points (the exception is 4 points for thrown), to which points are added for two handed weapons (1), for energy weapons (1), for big guns (2), for aimed shots (2, or 3 if with a scoped weapon), and for bursts as a secondary mode (2). The consequence is that whereas for instance the Minigun stays the same AP (3+1+2=6), the super sledge now costs 4 for the primary attack (3+1=4). Of course the old exceptions (like flares costing 1 AP) still apply. Unarmed has stayed the same as in the original, except that I've incorporated Magnus's common sense fix of making the secondary attacks cost only one additional AP. Having crippled arms also raises the AP cost, though only if the weapon is in the relevant arm or if you're using a two-handed weapon.

Of the AP-related perks and traits I needed to change at least one, given that I've already lowered the base cost for ranged weapons
from 4 to 3. I decided to make the fast shot trait something which makes you better at fast shots, so that the basic 10% penalty for snapshots now dissappears (the ranged penalty still applies however). The increased rate of fire/hth attacks perks still reduce the relevant AP costs, though (given that they are so incredibly overpowered at the moment), they also come with a base penalty of 10% to hit now. These perks are still huge advantages all the same of course.


ATTRIBUTE CHANGES

Spoiler: (highlight with mouse to read)
First, I've raised the cap on max strength. It makes sense that of the attributes that can be raised to super-human levels, strength should be the most obvious candidate. Of course you still can't reach higher that 10 strength with perks or at character creation, but it makes little sense that they would take the effort to make power armor, but restrict its capabilities to the level of an extraordinarily strong human. Same goes for Super Mutants: what sense does FEV make if the only result is that of a particularly strong human being? This change has allowed me to put the minimum strength requirement for weapons at the level I wanted it, namely "recoil" (2,3, or 4) + weapon weight divided by 3 (so a minigun is at the reasonable super-human requirement of 13 to handle perfectly, and the 10mm pistol remains at its original 3 strength minimum).

The second thing I've changed is that bulky armor now affects agility (not improved chance to hit, as it did before in my system). Now, starting with metal armor you (and all other critters) suffer a -1 penalty to agility, and starting with Power Armor, this becomes a -2 penalty.


CRITICAL HIT/FAILURE CHANGES

Spoiler: (highlight with mouse to read)
Let me start with critical hits.

The current system works like this: if you score a hit, this has a chance of being upgraded to a critical hit according to the following metric:

Code:
(CRITCHANCE + ((TOHIT−RND(1,100))/10))%


CRITCHANCE being the modifier of Luck + better criticals perks + finesse, and an extra roll being made if you have the Sniper or Slayer perk.

The one thing I don't agree with in this system is the fact that the to hit chance still plays a roll: why should a lucky shot to the eye have more of a chance of causing extra damage than a skill-driven one? Maybe this would make sense with the Living Anatomy perk, but that would be a future project. In my system, skill plays no role in getting critical hits.

The other thing is the way the Slayer and Sniper perks work. I know, I know, everyone loves them in spite of the balancing issues, but my main gripe with them isn't even the balancing aspect, but how boring they are. For instance, the first time I heard something about the almighty Sniper perk, I assumed it would have something to do with, you know, sniping.

Anyway, in my system they're still pretty damn powerful, only now they correspond a bit better with their titles/vault boy images. I've made the Slayer perk into the Conan the Barbarian type dealy it looks like from the image, meaning that your critical hit change rises bases on the number of men, women and children you've heard the lamentations of before killing them (divided by 10, natch). The sniper perk now increases the critical hit chance based on the distance of the target (so, with a sniper rifle at max distance, it gives +50 critical hit chance).

Other than these changes I've kept things more or less the same (I wasn't exactly sure what the original body part mods were, so I just did more or less the original penalties; i.e. eyes give +60% to critical hit chance, head +40%, etc.).

With critical misses, a miss gets upgraded to a critical miss in the current system like so:

Code:
(CRITCHANCE + ((TOHIT−RND(1,100))/10))%


The biggest problem with this in my view is that only misses can become critical failures, while many of the critical failures involve events like faulty ammo or defective weapons: a potential hit or miss should be irrelevant to such events. So, in my system, every shot/blow can potentially turn into a critical failure (in accordance with this I've raised the max possible to hit chance from the arbitrary 95% to 100%).

My other problem with the current system is the exact opposite of the one I had with critical hits: with critical misses skill should play a role, while it doesn't (i.e. whether or not you drop your spear in a frantic thrust should depend on your melee skill). I'll just use an example to show how the new system works:

Code:
if (get_sfall_global_int("weaponty") == small_arms_type) then begin
           if random(1,1000) > (get_critter_stat(attacker, STAT_pe)*10) + (has_skill(attacker, SKILL_REPAIR)) + (has_skill(attacker, SKILL_SMALL_GUNS)*2) then begin
          if random(1,100) > 65 + (get_critter_stat(attacker, STAT_lu)*3) then begin
             hit:=0;
          end
       end
    end


So there's now two rolls; the first checks against the players relevant skills and stats (in the example it's the repair skill needed to keep weapons and ammo in working condition, the perception needed to notice problems before it's too late and of course the skill of handling a fire arm; I've tried basing these required stats on the five possible failures per weapon type); the second roll checks against luck (another thing the current system inexplicably didn't do yet). Theoretically it is possible to avoid critical failures from being possible, but in practice it isn't (e.g. with Energy Weapons you would need 300 Science, 300 Repair, 300 Energy weapons skill and 10 PE).




DRUG CHANGES

Spoiler: (highlight with mouse to read)
What I have done is that super stims now raise your max hitpoints (temporarily) by 10, then raise your hitpoints by 50, then the first decreases -5, -5 and the latter -20, -20 (so it does heal something permanently at least: 10 hp - not enough to make you want to use it outside of battle). Regular stims now heal 20, then -8, -8 (so 4 hp permanent - again, you won't be using it outside of battle).

I've also changed Psycho while I was at it because I always found the system it used quite silly (you can suddenly resist 90% of bullet damage, but explosions, lasers, etc. still do the same damage?). Now it drastically raises your max hp (40) to reflect the additional punishment you can take, which then drops 50 after you start coming down (and of course back to normal after that). I had to sacrifice the initial INT penalty to make this new system work, but I doubt anybody found it had any gameplay consequences other than an exploit for becoming stupid temporarily (you can of course still use it for that purpose, except now you have to become addicted first).

Another reason I had to change Psycho was to free up critters' base DR for another project for improving a hitherto fairly useless stat, but which in the wasteland should be essential: repair. What I've done is that the armor you and your party members wear (at least, I'm pretty sure nobody else wears armor) changes based on the ability of the wearer to maintain it. Have a nice suit of power armor but not the slightest idea of how to keep it in good shape? The armor's DR will suffer as a result. Conversely, if you're extremely adept at armor maintanence (150+ repair) then the DR will actually increase. I would liked to have had this also apply to weapons, but I'm pretty sure that's impossible.


CONSISTENT LOCALIZATION

Spoiler: (highlight with mouse to read)
The issue it addresses is this: why is it that a shot at the target's eyes either hits the eyes or misses entirely; why is there no chance that it will miss the eyes, but hit the head or even the torso?

The system I use is that there's a certain percentage you have for hitting the desired body part, which rises as your chance to hit rises. Conversely, the chance to hit adjacent body parts diminishes, and that of "remote" body parts disappears (e.g., with a higher chance to hit the left arm, there is no longer a chance to hit, say, the right arm, and the chance to hit, say, the torso diminishes, until at 100+ percent to hit, you'll exclusively hit the left arm).

For most body parts the system is quite straightforward and the to hit system isn't changed, but there are two important exceptions: the eyes and the groin. These two are unique because they are entirely "embedded" in other body parts, namely the eyes in the head and the groin in the legs and torso. This is significant because the new system means that a 100% to hit when aiming for a certain bodypart no longer necessarily means a 100% hit on that body part but a 100% hit on the target. What this means is that whereas a 100% to hit when aiming for the torso is an automatic torso hit, a 100% to hit on the eyes can also mean a head hit. The practical consequence of this for the to hit system is that it no longer makes sense to give an eye shot a bigger basic penalty than a head shot; after all, whether your aiming for the eyes or the head "in general", you have the same chance of hitting the target.

Of course, in gameplay terms, this produces a problem; after all, say the head and the eyes are equally hard to hit, then why not always hit for the eyes instead of the head to get better criticals, etc.? The solution I've come up with is as follows: suppose you have a 10% chance to hit the eyes/head, then whichever target you choose, the chance to hit either body part is the exact same (roughly 1% for the eyes and 4% for the head). However, as your chance to hit rises, you become able to differentiate between the two, with the eye shot becoming progressively more difficult than the head shot. I believe this is a nice solution (in case you're wondering, this means I replace the basic penalties, which are as I said now equal, with a penalty in the "third phase" progressive nerfing).

Finally, an example to make the mechanics a bit more clear:

Code:

   else if (bodypart==eyes) then begin
       roll:=random(1,99);
       if (roll < (10 + (n*7))) then begin
          bodypart := eyes;
       end else if (roll < (50 + (n*7))) then begin
          bodypart := head;
       end else if (roll < (80 + (n*7))) then begin
          bodypart := torso;
       end else if (roll < (90 + (n*7))) then begin
          bodypart := random(left_arm,right_arm);
       end else begin
          bodypart := random(left_arm,right_arm);
       end
    end


the "n" variable stands for roughly the to hit chance divided by ten, so with more than 10% to hit, the chance to hit the eyes (upon a hit of course), becomes 17%.
View user's profileSend private message
Jim the Dinosaur
Wanderer
Wanderer


Joined: 06 Aug 2005
Posts: 430

PostPosted: Mon Aug 19, 2013 1:32 am Reply with quoteBack to top

FIXED MAX HITPOINTS

Spoiler: (highlight with mouse to read)
In my opinion the biggest contributor to mid-/late-game boringness other than the to hit problems already addressed is becoming a complete bullet sponge. It's completely absurd that even a low endurance character will be able to absorb more punishment by the end-game than a Super Mutant. Needless to say, fixing the max hitpoints (I've done so at 20+strength+endurance*5) creates potentially huge balancing issues. This doesn't address non-humans, making death claws and super mutants a tougher fight in all likelihood. This I don't mind (I always felt the big baddies were a bit tame in Fallout 2), but some might.




(PASSIVE) ARMOR REPAIR

Spoiler: (highlight with mouse to read)
With this the armor's damage resistances (so not thresholds) get adjusted based on the wearer's skills. Here is the system I use:

Code:

#define normal(x)                       (-3 + (has_skill(x, SKILL_REPAIR)/50))
#define laser(x)                       (-5 + (has_skill(x, SKILL_REPAIR)/50) + (has_skill(x, SKILL_SCIENCE)/50))
#define plasma(x)                       (-5 + (has_skill(x, SKILL_REPAIR)/50) + (has_skill(x, SKILL_SCIENCE)/50))
#define explosion(x)                     (-5 + (has_skill(x, SKILL_REPAIR)/50) + (has_skill(x, SKILL_TRAPS)/50))
#define electrical(x)                     (-5 + (has_skill(x, SKILL_REPAIR)/50) + (has_skill(x, SKILL_SCIENCE)/50))
#define fire(x)                       (-5 + (has_skill(x, SKILL_REPAIR)/50) + (has_skill(x, SKILL_TRAPS)/50))


This formula then gets multiplied based on how heavy the armor is (leather*1, metal*2, etc.); meaning that if a critter has 50 traps skill and 50 repair skill and is wearing metal armor, his explosive damage resistance gets changed by (-5+1+1)*2= -6%. There's still a lot more I need to do with this, mainly to reflect the fact that places like the Enclave have specialists for armor maintanence and the like.


DRUG/HEALTH SYSTEM CHANGES

Spoiler: (highlight with mouse to read)
This was already in the last version, but given that it's now finally working properly, I might as well sum up the changes:

- (Super-)stimpaks are now combat stimulants rather than health potions, they heal only minor wounds (4 for regular, 10 for super), and mainly serve as a temporary measure (16 temp hp for regular, 40 temp hp + 10 extra temp max hitpoints for super), which means that taking more than your endurance allows will be deadly. To avoid exploitation, injecting someone other than a party member with a stimpak causes him to attack (which makes sense).

- Because I'm not a big fan of the way the first aid skill works as an active skill, I've decided to make it a passive skill through its raising the Healing Rate. So now "resting" also accounts for medical treatment (which makes sense; who ever slept off a bullet wound?). So now instead of pumping everyone full of stims after a battle, taking a medical break will be necessary.

- Psycho is now also different: instead of the silly Damage Resistance mod (you can block bullets, but not lasers?) it now drastically raises you max hit points to represent the additional punishment you can take, but also has a harsh comedown.

One final note concerning the exploit blocking system; a lot of people dislike this in sfall because it takes away the only stealth kill that works. To fix this (though this is a longer term project) I want to make an assassination system through dialogue (that is, if you're in stealth mode when entering dialogue you'll get a range of options with relevant skill checks). I'm guessing this will allow us to do more fun stuff like have guards react and investigate, etc.


PLAYER MORALE SYSTEM

Spoiler: (highlight with mouse to read)
I always felt it was a bit unfair how NPC's all have the wonderfully human characteristic of occasionally bursting into fits of abject fear, while the player can happily blast away while having half his body shot off.

Now, I'm sure a lot of you like the idea of being some kind of B-movie action hero (it's the same debate as always about Fallout whether you like it for the Reno sillyness or grave Mark Morgan-y graveness - the curse of a game which can't decide on what it wants to be I guess), but I like my heroes a bit more human. Don't worry, you won't be forced to run away, it's just that if you fail a morale check at the beginning of a turn you get one of three effects, each notified by a red lettered floater:

Code:

{142}{}{[Panic suddenly takes a hold of you, and your legs momentarily feel like they are made of lead.]}
{143}{}{[Panic suddenly hits you, and steadying your hands becomes almost impossible.]}
{144}{}{[You're suddenly overcome with fear of the enemy, and convincing yourself to attack would take more effort than ever.]}


The first causes your movement to cost twice as many AP's; the second causes you to get a hefty 40% penalty to hit; and the third raises your attacking AP cost by two (unfortunately the numbers don't update immediately for this last one, but it does work).

The morale check itself works like this: you always start off with zero chance of morale failure, then as you kill more and more humans (especially children) it starts building up. It also rises when you're hurt, and goes back down when you're healed. You can bring down the morale failure chance by drinking alcoholic beverages.

To make things more interesting I've added some dialogue to Cameron in the Temple of Trials where you can change aspects of this morale system. The dialogue is this:


Code:


{313}{}{. I have the honor of being your final challenge. My task is to first test your resolve, then your physical prowess.}
{314}{}{Listen, me standing here covered in giant ant-entrails or whatever the hell this purple stuff is should be proof enough of my resolve, buddy, so you can just skip that part right away.}
{315}{}{How do you plan on testing my resolve?}
{316}{}{Re...solve?}
{317}{}{Just one simple question. This village has shielded you all your life from the horrors of the wasteland; but soon you will have to face these horrors head on. How do you plan on coping with this?}
{318}{}{I'll probably have some liquid resolve now and then to steady the nerves. But if the Elder asks, tell her I said something about the plight of the village, or whatever.}
{319}{}{My resolve will not falter because I will know that my cause is just.}
{320}{}{Let's just say that I'll make sure that these horrors befall others, not me.}
{321}{}{I'll cope just fine, now get to the last part already.}
{322}{}{[Your venomous breath tells Cameron all he needs to know.]}
{323}{}{Me know good.}
{324}{}{Maybe me horror.}
{326}{}{Muh. [You can't help but wonder whether you couldn't have been more eloquent there.]}
{325}{}{Very well. As to your final challenge, to continue in your quest you must defeat me in unarmed combat. Shall we begin?}


As you can see you'll have three options to change things up: (1) the "liquid resolve" options makes alcohol a more effective morale booster, while also making the stuff more addictive, (2) The "righteous" option makes increases in karma improve your morale, while the killing of humans more easily shakes your resolve, and (3) the selfish option makes killing humans not factor in at all, but makes getting hurt yourself far more demoralizing.


SUPPLY AND DEMAND SYSTEM

Spoiler: (highlight with mouse to read)
Code:

procedure start;


#include "C:\Program Files (x86)\GOG.com\Fallout 2 Mapper\scripts\HEADERS\sfall.h"
#include "C:\Program Files (x86)\GOG.com\Fallout 2 Mapper\scripts\HEADERS\define.h"
#include "C:\Program Files (x86)\GOG.com\Fallout 2 Mapper\scripts\HEADERS\command.h"


procedure start begin
  variable critter;
  variable container;
  variable n;
    variable amount;
  if game_loaded then begin
    set_global_script_type(1);
    set_global_script_repeat(100);
  end else begin
  if get_sfall_global_int("priceset") ^ 524 then begin
    n:=get_sfall_global_int("priceset");
    //display_msg("GVAR SET" + get_sfall_global_int("priceset"));
  if (get_sfall_global_int("priceset") == n)  then begin
      foreach critter in list_as_array(LIST_CRITTERS) begin
      amount+=obj_is_carrying_obj_pid(critter,n);
    //display_msg("amount" + amount);
      end
      foreach container in list_as_array(LIST_GROUNDITEMS) begin
      amount+=obj_is_carrying_obj_pid(container,n);
      end
    if amount > 0 and not (n == 41) then begin
    set_proto_data(n, 120, (pid_cost(n)/(amount)));
    //display_msg("cost" + pid_cost(n));
    end
    amount:=0;
    set_sfall_global("priceset", n+1); 
    //display_msg("what" + n);
    end
    end
  end
end
(Had to change the "lesser than" symbol into ^ for the site)


The sequence gets fired by the player entering a new map, which causes the sfall global to be reset to 1 (hence the dude_obj script in the download; if you're wary of accepting a stranger's dude_obj, then just add "set_sfall_global("priceset", 1);" under map_enter_p_proc and you're set). The script checks for every item proto (1-524) how many of it someone or some container is carrying, and if this number is more than 0 the price gets adjusted. For the moment, the formula is still quite (too) simple: original price divided by amount on map. The practical consequence is that, for instance, your spear will now net only 13 dollars in Arroyo, instead of the original 80. I've tested it in the Arroyo and Klamath maps, and it seems to work great. Hope you find some use for it (the download is in the original post).
View user's profileSend private message
Redeye
I lied
I lied


Joined: 07 Mar 2005
Posts: 4164
Location: filth

PostPosted: Fri Aug 23, 2013 1:50 am Reply with quoteBack to top

View user's profileSend private message
Jim the Dinosaur
Wanderer
Wanderer


Joined: 06 Aug 2005
Posts: 430

PostPosted: Fri Aug 23, 2013 3:17 pm Reply with quoteBack to top

the bots like my thread. they must know this is where the action is. aiee
View user's profileSend private message
Jim the Dinosaur
Wanderer
Wanderer


Joined: 06 Aug 2005
Posts: 430

PostPosted: Sun Aug 25, 2013 2:32 pm Reply with quoteBack to top

You do that buddy!
View user's profileSend private message
Display posts from previous:      
Post new topicReply to topic


Jump to:  



View next topic
View previous topic
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group