mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
580 lines
12 KiB
Lua
580 lines
12 KiB
Lua
|
|
--[[
|
||
|
|
| This file was obtained through the combined efforts
|
||
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
||
|
|
|
|
||
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
||
|
|
|
|
||
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||
|
|
--]]
|
||
|
|
|
||
|
|
|
||
|
|
-- Copyright (c) 2018-2020 TFA Base Devs
|
||
|
|
|
||
|
|
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
|
-- of this software and associated documentation files (the "Software"), to deal
|
||
|
|
-- in the Software without restriction, including without limitation the rights
|
||
|
|
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
|
-- copies of the Software, and to permit persons to whom the Software is
|
||
|
|
-- furnished to do so, subject to the following conditions:
|
||
|
|
|
||
|
|
-- The above copyright notice and this permission notice shall be included in all
|
||
|
|
-- copies or substantial portions of the Software.
|
||
|
|
|
||
|
|
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
|
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
|
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
|
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
|
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
|
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||
|
|
-- SOFTWARE.
|
||
|
|
|
||
|
|
-- This file is holding seamless translation of older versions of data to newer
|
||
|
|
-- versions of data
|
||
|
|
|
||
|
|
TFA.LatestDataVersion = 1
|
||
|
|
|
||
|
|
TFA.DataVersionMapping = {
|
||
|
|
[0] = {
|
||
|
|
{
|
||
|
|
old_path = "DrawCrosshairIS",
|
||
|
|
new_path = "DrawCrosshairIronSights",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "FiresUnderwater",
|
||
|
|
new_path = "Primary.FiresUnderwater",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "PenetrationMaterials",
|
||
|
|
new_path = "Primary.PenetrationMaterials",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "MaxPenetrationCounter",
|
||
|
|
new_path = "Primary.MaxSurfacePenetrationCount",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "MaxPenetration",
|
||
|
|
new_path = "Primary.MaxSurfacePenetrationCount",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "IronRecoilMultiplier",
|
||
|
|
new_path = "Primary.IronRecoilMultiplier",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "MoveSpeed",
|
||
|
|
new_path = "RegularMoveSpeedMultiplier",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "IronSightsMoveSpeed",
|
||
|
|
new_path = "AimingDownSightsSpeedMultiplier",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "Shotgun",
|
||
|
|
new_path = "LoopedReload",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "ShellTime",
|
||
|
|
new_path = "LoopedReloadInsertTime",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "CrouchPos",
|
||
|
|
new_path = "CrouchViewModelPosition",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "CrouchAng",
|
||
|
|
new_path = "CrouchViewModelAngle",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "data.ironsights",
|
||
|
|
new_path = "Secondary.IronSightsEnabled",
|
||
|
|
upgrade = function(value) return value == 1 end,
|
||
|
|
downgrade = function(value) return value and 1 or 0 end,
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "Secondary.IronFOV",
|
||
|
|
new_path = "Secondary.OwnerFOV",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "IronViewModelFOV",
|
||
|
|
new_path = "Secondary.ViewModelFOV",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "DoProceduralReload",
|
||
|
|
new_path = "IsProceduralReloadBased",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "ProceduralReloadEnabled",
|
||
|
|
new_path = "IsProceduralReloadBased",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "Akimbo",
|
||
|
|
new_path = "IsAkimbo",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "AkimboHUD",
|
||
|
|
new_path = "EnableAkimboHUD",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "IronInSound",
|
||
|
|
new_path = "Secondary.IronSightsInSound",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "IronOutSound",
|
||
|
|
new_path = "Secondary.IronSightsOutSound",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "DisableChambering",
|
||
|
|
new_path = "Primary.DisableChambering",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "DisplayFalloff",
|
||
|
|
new_path = "Primary.DisplayFalloff",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "SpreadPattern",
|
||
|
|
new_path = "Primary.SpreadPattern",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "SpreadBiasYaw",
|
||
|
|
new_path = "Primary.SpreadBiasYaw",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "SpreadBiasPitch",
|
||
|
|
new_path = "Primary.SpreadBiasPitch",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "VMPos",
|
||
|
|
new_path = "ViewModelPosition",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "VMAng",
|
||
|
|
new_path = "ViewModelAngle",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "VMPos_Additive",
|
||
|
|
new_path = "AdditiveViewModelPosition",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "RunSightsPos",
|
||
|
|
new_path = "SprintViewModelPosition",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "RunSightsAng",
|
||
|
|
new_path = "SprintViewModelAngle",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "IronSightsPos",
|
||
|
|
new_path = "IronSightsPosition",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "IronSightsAng",
|
||
|
|
new_path = "IronSightsAngle",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "Bodygroups_V",
|
||
|
|
new_path = "ViewModelBodygroups",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "Bodygroups_W",
|
||
|
|
new_path = "WorldModelBodygroups",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "CenteredPos",
|
||
|
|
new_path = "CenteredViewModelPosition",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "CenteredAng",
|
||
|
|
new_path = "CenteredViewModelAngle",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "Offset",
|
||
|
|
new_path = "WorldModelOffset",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "ProceduralHolsterPos",
|
||
|
|
new_path = "ProceduralHolsterPosition",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "ProceduralHolsterAng",
|
||
|
|
new_path = "ProceduralHolsterAngle",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "VElements",
|
||
|
|
new_path = "ViewModelElements",
|
||
|
|
},
|
||
|
|
|
||
|
|
{
|
||
|
|
old_path = "WElements",
|
||
|
|
new_path = "WorldModelElements",
|
||
|
|
},
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
local function identity(...) return ... end
|
||
|
|
|
||
|
|
for version = 0, #TFA.DataVersionMapping do
|
||
|
|
for i, data in ipairs(TFA.DataVersionMapping[version]) do
|
||
|
|
if not isfunction(data.upgrade) then data.upgrade = identity end
|
||
|
|
if not isfunction(data.downgrade) then data.downgrade = identity end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
TFA.PathParseCache = {}
|
||
|
|
TFA.PathParseCacheTR = {}
|
||
|
|
TFA.StatPathRemapCache = {}
|
||
|
|
TFA.PathParseCacheDirect = {}
|
||
|
|
TFA.PathParseChildren = {}
|
||
|
|
|
||
|
|
local PathParseCache = TFA.PathParseCache
|
||
|
|
local PathParseCacheTR = TFA.PathParseCacheTR
|
||
|
|
local PathParseCacheDirect = TFA.PathParseCacheDirect
|
||
|
|
local StatPathRemapCache = TFA.StatPathRemapCache
|
||
|
|
local PathParseChildren = TFA.PathParseChildren
|
||
|
|
local string_Explode = string.Explode
|
||
|
|
local ipairs = ipairs
|
||
|
|
local pairs = pairs
|
||
|
|
local string_sub = string.sub
|
||
|
|
local tonumber = tonumber
|
||
|
|
local table_Copy = table.Copy
|
||
|
|
local table_concat = table.concat
|
||
|
|
local istable = istable
|
||
|
|
local string_format = string.format
|
||
|
|
|
||
|
|
local function doDowngrade(path, migrations)
|
||
|
|
for i, data in ipairs(migrations) do
|
||
|
|
if data.new_path == path then
|
||
|
|
return data.old_path, data.upgrade
|
||
|
|
elseif path:StartWith(data.new_path) and path[#data.new_path + 1] == '.' then
|
||
|
|
return data.old_path .. path:sub(#data.new_path + 1), data.upgrade
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return path
|
||
|
|
end
|
||
|
|
|
||
|
|
local function doUpgrade(path, migrations)
|
||
|
|
for i, data in ipairs(migrations) do
|
||
|
|
if data.old_path == path then
|
||
|
|
return data.new_path, data.downgrade
|
||
|
|
elseif path:StartWith(data.old_path) and path[#data.old_path + 1] == '.' then
|
||
|
|
return data.new_path .. path:sub(#data.old_path + 1), data.downgrade
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return path
|
||
|
|
end
|
||
|
|
|
||
|
|
function TFA.RemapStatPath(path, path_version, structure_version)
|
||
|
|
local cache_path = path
|
||
|
|
|
||
|
|
if path_version == nil then path_version = 0 end
|
||
|
|
if structure_version == nil then structure_version = 0 end
|
||
|
|
|
||
|
|
-- version do not match
|
||
|
|
if path_version ~= structure_version then
|
||
|
|
cache_path = string_format("%d_%d_%s", path_version, structure_version, path)
|
||
|
|
end
|
||
|
|
|
||
|
|
local get_cache = StatPathRemapCache[cache_path]
|
||
|
|
if get_cache ~= nil then return get_cache end
|
||
|
|
|
||
|
|
if cache_path ~= path then
|
||
|
|
-- downgrade path
|
||
|
|
if path_version > structure_version then
|
||
|
|
for version = path_version, structure_version, -1 do
|
||
|
|
local mapping = TFA.DataVersionMapping[version]
|
||
|
|
|
||
|
|
if istable(mapping) then
|
||
|
|
path = doDowngrade(path, mapping)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else -- upgrade path
|
||
|
|
for version = path_version, structure_version do
|
||
|
|
local mapping = TFA.DataVersionMapping[version]
|
||
|
|
|
||
|
|
if istable(mapping) then
|
||
|
|
path = doUpgrade(path, mapping)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
StatPathRemapCache[cache_path] = path
|
||
|
|
return StatPathRemapCache[cache_path]
|
||
|
|
end
|
||
|
|
|
||
|
|
function TFA.GetStatPathChildren(path, path_version, structure_version)
|
||
|
|
-- version do not match
|
||
|
|
if path_version ~= structure_version then
|
||
|
|
path = TFA.RemapStatPath(path, path_version, structure_version)
|
||
|
|
end
|
||
|
|
|
||
|
|
if not PathParseChildren[path] then
|
||
|
|
TFA.GetStatPath(path, path_version, structure_version)
|
||
|
|
end
|
||
|
|
|
||
|
|
return PathParseChildren[path].list
|
||
|
|
end
|
||
|
|
|
||
|
|
local function concat_to(tab, to)
|
||
|
|
local str = tab[1]
|
||
|
|
|
||
|
|
for i = 2, to do
|
||
|
|
str = str .. '.' .. tab[i]
|
||
|
|
end
|
||
|
|
|
||
|
|
return str
|
||
|
|
end
|
||
|
|
|
||
|
|
local function concat_from(tab, from)
|
||
|
|
local str = tab[from]
|
||
|
|
|
||
|
|
for i = from + 1, #tab do
|
||
|
|
str = str .. '.' .. tab[i]
|
||
|
|
end
|
||
|
|
|
||
|
|
return str
|
||
|
|
end
|
||
|
|
|
||
|
|
function TFA.GetStatPath(path, path_version, structure_version, no_translate)
|
||
|
|
local cache_path = path
|
||
|
|
|
||
|
|
if path_version == nil then path_version = 0 end
|
||
|
|
if structure_version == nil then structure_version = 0 end
|
||
|
|
|
||
|
|
-- version do not match
|
||
|
|
if path_version ~= structure_version then
|
||
|
|
cache_path = string_format("%d_%d_%s", path_version, structure_version, path)
|
||
|
|
end
|
||
|
|
|
||
|
|
local _PathParseCache = no_translate and PathParseCacheTR or PathParseCache
|
||
|
|
local get_cache = _PathParseCache[cache_path]
|
||
|
|
if get_cache ~= nil then return get_cache[1], get_cache[2], get_cache[3] end
|
||
|
|
|
||
|
|
local fn, fnGet
|
||
|
|
|
||
|
|
if cache_path ~= path then
|
||
|
|
-- downgrade
|
||
|
|
if path_version > structure_version then
|
||
|
|
for version = path_version, structure_version, -1 do
|
||
|
|
local mapping = TFA.DataVersionMapping[version]
|
||
|
|
|
||
|
|
if istable(mapping) then
|
||
|
|
path, fnGet = doDowngrade(path, mapping)
|
||
|
|
|
||
|
|
if fnGet and fnGet ~= identity then
|
||
|
|
if not fn then
|
||
|
|
fn = fnGet
|
||
|
|
else
|
||
|
|
local _fn = fn
|
||
|
|
function fn(...) return fnGet(_fn(...)) end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else -- upgrade
|
||
|
|
for version = path_version, structure_version do
|
||
|
|
local mapping = TFA.DataVersionMapping[version]
|
||
|
|
|
||
|
|
if istable(mapping) then
|
||
|
|
path, fnGet = doUpgrade(path, mapping)
|
||
|
|
|
||
|
|
if fnGet and fnGet ~= identity then
|
||
|
|
if not fn then
|
||
|
|
fn = fnGet
|
||
|
|
else
|
||
|
|
local _fn = fn
|
||
|
|
function fn(...) return fnGet(_fn(...)) end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
get_cache = string_Explode(".", path, false)
|
||
|
|
|
||
|
|
do
|
||
|
|
local children = PathParseChildren[get_cache[1]]
|
||
|
|
|
||
|
|
if not children then
|
||
|
|
children = {
|
||
|
|
list = {get_cache[1]},
|
||
|
|
children = {}
|
||
|
|
}
|
||
|
|
|
||
|
|
PathParseChildren[get_cache[1]] = children
|
||
|
|
end
|
||
|
|
|
||
|
|
local childrens = {children}
|
||
|
|
|
||
|
|
for i = 2, #get_cache do
|
||
|
|
local obj = get_cache[i]
|
||
|
|
local path2 = concat_to(get_cache, i)
|
||
|
|
|
||
|
|
for i3 = 1, #childrens do
|
||
|
|
local list = childrens[i3].list
|
||
|
|
local hit = false
|
||
|
|
|
||
|
|
for i2 = 1, #list do
|
||
|
|
if list[i2] == path2 then
|
||
|
|
hit = true
|
||
|
|
break
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if not hit then
|
||
|
|
table.insert(list, path2)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if not children.children[obj] then
|
||
|
|
children.children[obj] = {
|
||
|
|
list = {path2},
|
||
|
|
children = {}
|
||
|
|
}
|
||
|
|
end
|
||
|
|
|
||
|
|
if not PathParseChildren[path2] then
|
||
|
|
PathParseChildren[path2] = {
|
||
|
|
list = {path2},
|
||
|
|
children = {}
|
||
|
|
}
|
||
|
|
end
|
||
|
|
|
||
|
|
children = children.children[obj]
|
||
|
|
table.insert(childrens, children)
|
||
|
|
table.insert(childrens, PathParseChildren[path2])
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if not no_translate then
|
||
|
|
if get_cache[1] == "Primary" then
|
||
|
|
get_cache[1] = "Primary_TFA"
|
||
|
|
elseif get_cache[1] == "Secondary" then
|
||
|
|
get_cache[1] = "Secondary_TFA"
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
for k, v in ipairs(get_cache) do
|
||
|
|
get_cache[k] = tonumber(v) or v
|
||
|
|
end
|
||
|
|
|
||
|
|
_PathParseCache[cache_path] = {get_cache, path, fn or identity}
|
||
|
|
return get_cache, path, fn or identity
|
||
|
|
end
|
||
|
|
|
||
|
|
function TFA.GetStatPathRaw(path)
|
||
|
|
local get_cache = PathParseCacheDirect[path]
|
||
|
|
if get_cache ~= nil then return get_cache end
|
||
|
|
|
||
|
|
local t_stbl = string_Explode(".", path, false)
|
||
|
|
|
||
|
|
for k, v in ipairs(t_stbl) do
|
||
|
|
t_stbl[k] = tonumber(v) or v
|
||
|
|
end
|
||
|
|
|
||
|
|
PathParseCacheDirect[path] = t_stbl
|
||
|
|
return t_stbl
|
||
|
|
end
|
||
|
|
|
||
|
|
local GetStatPathRaw = TFA.GetStatPathRaw
|
||
|
|
|
||
|
|
do
|
||
|
|
local function get(self, path)
|
||
|
|
local value = self[path[1]]
|
||
|
|
|
||
|
|
for i = 2, #path do
|
||
|
|
if not istable(value) then return end
|
||
|
|
value = value[path[i]]
|
||
|
|
end
|
||
|
|
|
||
|
|
return value
|
||
|
|
end
|
||
|
|
|
||
|
|
local function set(self, path, val)
|
||
|
|
if #path == 1 then
|
||
|
|
if self[path[1]] == nil then
|
||
|
|
self[path[1]] = val
|
||
|
|
end
|
||
|
|
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local value = self[path[1]]
|
||
|
|
|
||
|
|
if value == nil then
|
||
|
|
self[path[1]] = {}
|
||
|
|
value = self[path[1]]
|
||
|
|
end
|
||
|
|
|
||
|
|
for i = 2, #path - 1 do
|
||
|
|
if not istable(value) then return end
|
||
|
|
if value[path[i]] == nil then value[path[i]] = {} end
|
||
|
|
value = value[path[i]]
|
||
|
|
end
|
||
|
|
|
||
|
|
if istable(value) and value[path[#path]] == nil then
|
||
|
|
value[path[#path]] = val
|
||
|
|
elseif not istable(value) then
|
||
|
|
print('[TFA Base] unable to fill gap for older version in meta structure of ' .. table_concat(path, '.'))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function TFA.FillMissingMetaValues(SWEP)
|
||
|
|
for version = TFA.LatestDataVersion, 0, -1 do
|
||
|
|
local mapping = TFA.DataVersionMapping[version]
|
||
|
|
|
||
|
|
if istable(mapping) then
|
||
|
|
for i, data in ipairs(mapping) do
|
||
|
|
local getVal = get(SWEP, GetStatPathRaw(data.new_path))
|
||
|
|
|
||
|
|
if getVal ~= nil then
|
||
|
|
set(SWEP, GetStatPathRaw(data.old_path), data.downgrade(getVal))
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|