Fallout Tactics mod Modifying perks

Bigwilleh

First time out of the vault
Hello,

How does one modify perks?

I'm having a look at equilibrium, and making some balance and design tweaks to get it to my liking (dramatically increasing the risk, xp reward, and ammo/consumable reward for random encounters, adding rare spawn boss creeps to humanoid random encounters, changing drug balancing to do away with outrageous stacking without risk *cough cough buffout*).

One area where I'd like to touch on the game balance is in perks. Particularly, I find that although its nice to see AC perks that are actually worth taking, they are outrageously strong at the low levels they are available (level 6 with 2 ranks of dodger, suddenly mission raiders literally can't hit you).

TL;DR: re-balancing equilibrium to my liking, want to adjust perks, how do?
 
This is totally doable with Melindil current BOS SE (script engine). The only downside is there is that it is very new and in development, so there is not a lot of documentation available for it yet.
 
I had a look at it, and it looks like it scripts hex edits to the executable. This seems like it would mostly be useful to someone who is already proficient with hex editing, but I have no idea how it works.

Its something on my to do list to look into it.
 
It is a bit beyond me too, but I can say that most of the time it does not require any hex editing knowledge to be used extensively, but rather some other type of coding knowledge : LUA code. Whatever it is, the code have some intuitive components and can be added by editing two specific files that comes with Scripting Engine, "FTSE_config.json" (listing HEX code replacements or patches) and "ftse.lua" (containing the LUA codes and functions).

I can also point out that FOTSE already comes with a big bunch of codes and patches, so you just have to unable or disable them to benefit from a wide variety of fixes and customizations to your game.

Here is an example of LUA code used :

Code:
--[[
Leave these definitions alone - they are needed to interface
with the C++ DLL library.
--]]

ACTOR_TABLE_PERM = 0
ACTOR_TABLE_DERIVED = 1
ACTOR_TABLE_TEMPORARY = 2
ACTOR_TABLE_CURRENT = 3

COMBATLOG_SYSTEM = 0
COMBATLOG_FEW = 1
COMBATLOG_DEFAULT = 2
COMBATLOG_ALL = 3

--[[
The following code is used to convert between the internal
game timer (millisecond resolution) to in-game date and time.
--]]

month_end_days = { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}

function MsecToDayHMS(ms,scale)
    if scale > 0 then
      ms = ms * 3
    end
    d = (ms // 86400000)
    h = (ms // 3600000)%24
    m = (ms // 60000)%60
    s = (ms // 1000)%60
    ms = ms % 1000
    gametime = {
      year = 0,
      month = 0,
      day = d,
      hour = h,
      minute = m,
      second = s,
      msec = ms
    }
    return gametime
end

function AddBaseToGameTime(gametime)

    -- add base days, hours and minute
    gametime["minute"] = gametime["minute"] + 29
    gametime["hour"] = gametime["hour"] + 6
    gametime["day"] = gametime["day"] + 2197*365

    -- normalize hours and minutes
    if gametime["minute"] > 59 then
      gametime["minute"] = gametime["minute"] - 60
      gametime["hour"] = gametime["hour"] + 1
    end
    if gametime["hour"] > 23 then
      gametime["hour"] = gametime["hour"] - 24
      gametime["day"] = gametime["day"] + 1
    end
   
    -- calculate year and day within year
    gametime["year"] = gametime["day"]//365
    gametime["day"] = gametime["day"] % 365 + 1

    -- Get month and day within month
    mo = gametime["day"] // 30
    if mo == 0 or gametime["day"] > month_end_days[mo] then
      mo = mo + 1
    end
    if mo > 1 then
      gametime["day"] = gametime["day"] - month_end_days[mo-1]
    end
    gametime["month"] = mo
    return gametime
end

-- Burst bug fix code
function CalculateChance(chance,intended,angle)
  if intended == false then
    chance = math.min(chance,40)
    if angle > 5.0 then
      chance = math.floor(chance * (21.3 - angle) / 16.3)
    end
  end
  return chance
end

function CalculateShare(chance)
  return math.min(chance,70)  
end

function OnBurstAttack(attacker,shots,target_table)
  results = {}
  totalshare = 0
  for _,tgt in ipairs(target_table) do
    share = CalculateShare(CalculateChance(tgt["hit_chance"],tgt["intended"],tgt["angle"]))
    totalshare = totalshare + share
  end
  totalshare = math.max(totalshare,100)
  shotsleft = shots
  for _,tgt in ipairs(target_table) do
    chance = CalculateChance(tgt["hit_chance"],tgt["intended"],tgt["angle"])
    tgtshots = math.min(shotsleft,math.max(1,math.floor(shots * CalculateShare(chance) / totalshare)))
    shotsleft = shotsleft - tgtshots
    myhits = 0
    for i=1,tgtshots do
      roll = math.floor(math.random()*100)
      if roll < chance then
        myhits = myhits + 1
      end
    end
    result = {id=tgt["actor"]["id"], hits=myhits }
    table.insert(results, result)
  end
  return results
end

math.randomseed(os.time())
-- Modifiable functions begin below -----------------


function DefaultStyleChanges(style)
  style:SetColorDefaultText(0.35,0.35,0.35)
  style:SetColorHighlightText(1.0,0.5,0.0)
  style:SetColorOptionsPages(0.20,0.20,0.20)
  style:SetColorPanelTitles(1.0,1.0,1.0)
  style:SetColorBuffs(1.0,1.0,0.0)
  style:SetColorDebuffs(1.0,0.0,0.0)
  style:SetColorTags(1.0,1.0,0.0)
end
 
OH WOW. I could get lost in that for days...! I'll try not to look at it too much. :D Incredible work here. What a nice period for modding tactics.
 
Back
Top