Divergent/mods/1st Person Visible Body/gamedata/scripts/_u.script

467 lines
12 KiB
Plaintext

--[[ ----------------------------------------------------------------------------------------------
Ïëàòôîðìû: CS 1.5.10, CoP 1.6.02
Îïèñàíèå : Ðàçëè÷íûå óòèëèòû äëÿ ðàáîòû ñ äàííûìè
Ïîääåðæêà: 2013 © Shoker Weapon Mod
Àâòîðû : Shoker, <...>
Shoker Weapon Mod 2.1 port, modified by Wang_Laoshi (Ethereal) to work with Anomaly mod. Thanks a lot to the original creators of this mod - Shoker, ÐèêîøåÒ and SWM Team in general.
--]] ----------------------------------------------------------------------------------------------
--[[
TODO:
* Ïðè ÷òåíèè ÷åðåç ltx() èç ini-ôàéëà ìîæåò ñîâïàñòü èìÿ ñåêöèè è ñòðîêà äëÿ ÷òåíèÿ ñ ïîõîæåé
ñåêöèåé èç system_ini() èëè ëþáîãî äðóãîãî ini, èç çà ÷åãî îíà áóôåðèçèðóåòñÿ è ïåðåáü¸ò çíà÷åíèÿ èç íèõ
--]]
--************************************************************--
--***********************[ßäðî ñêðèïòà]***********************--
--************************************************************--
local _SN = script_name()
--**************************************************************--
--********************[Ôóíêöèîíàëüíàÿ ÷àñòü]********************--
--**************************************************************--
--\\ Èç âåêòîðà "âïåð¸ä" âîçâðàùàåò âåêòîð "âïðàâî" è âåêòîð "ââåðõ" (Roll íå ó÷èòûâàåòñÿ)
--\\ Ñïàñèáî malandrinus çà ôîðìóëû
function get_all_direction(dir)
--* "Âïðàâî"
local dir_right = vector()
dir_right:crossproduct(dir, vector():set(0,1,0))
dir_right = dir_right:normalize()
--* "Ââåðõ"
local dir_up = vector()
dir_up:crossproduct(dir_right, dir)
dir_up = dir_up:normalize()
return dir_right:invert(), dir_up
end
--\\ Ïðèíèìàåò êîîðäèíàòû íà çåìëå è ïðåâðàùàåò èõ â êîîðäèíàòû äëÿ ýêðàíà
--\\ Ìîæíî èñïîëüçîâàòü â öåëåóêàçàòåëÿõ (malandrinus)
function point_to_hud(point)
local dev = device()
local scr_w = dev.width
local scr_h = dev.height
local fov2 = (dev.fov/2) * (math.pi/180)
local scr_dist = 0.5 * scr_h / math.tan(fov2)
local ppp = vector():sub(point, dev.cam_pos)
local dp = dev.cam_dir:dotproduct(ppp)
local x = 512 + dev.cam_right:dotproduct(ppp) * scr_dist / dp * (1024/scr_w)
local y = 384 - dev.cam_top:dotproduct(ppp) * scr_dist / dp * (768/scr_h)
return x, y
end
--\\ Âåêòîð X,Y â óãëàõ ïåðåâîäèò â äèðåêöèþ
function angle_to_direction(oangle)
local yaw = oangle.y
local pitch = oangle.x
return vector():setHP(yaw,pitch):normalize()
end
--\\ Ðýíäîì äâóõ float-÷èñåë ñ ïîääåðæêîé îäíîãî ðàçðÿäà
function frandom(n1, n2)
n1 = n1 * 10
n2 = n2 * 10
return (math.random(n1, n2) / 10)
end
local ltxBuffer = {} --> Õðàíèò óæå çàãðóæåííûå äàííûå èç êîíôèãîâ
--\\ Âîçâðàùàåò çíà÷åíèå èç ñåêöèè â êîíôèãàõ
-- sec - ñåêöèÿ
-- line - ñòðîêà
-- *mode - ðåæèì ÷òåíèÿ, ïî óìîë÷àíèþ ÷èòàåò ÷èñëî ñ òî÷êîé ("str", "tbl1", "bol", "num", "numf")
-- *ini_file - ini-êîíôèã îòêóäà íàäî ÷èòàòü, ïî óìîë÷àíèþ ÷èòàåò èç system.ltx è ïîäêë. ê íåìó ôàéëàõ
-- Âíèìàíèå: â ñëó÷àå îòñóòñòâèÿ ñåêöèè\ñòðîêè â êîíôèãå - âûëåòà íå áóäåò, òàê ÷òî âñå òàêèå ìåñòà
-- ïðîâåðÿòü ñîîòâ. ôóíêöèÿìè ñàìèì. Ñäåëàíî äëÿ óïðîùåíèÿ êîäà.
function ltx(sec, line, mode, ini_file)
if sec == nil then
_abort(_SN, "ltx", "sec (%s)(%s)", tostring(line), tostring(mode))
end
if not ltxBuffer[sec] then
ltxBuffer[sec] = {}
end
local result = ltxBuffer[sec][line]
if result ~= nil then
--* Âåêòîðà âîçâðàùàþòñÿ êàê ññûëêè! Ïîýòîìó èõ íóæíî êîïèðîâàòü
if type(result) == "userdata" then
return utils.vector_copy_by_val(result)
end
return result
end --> Íåò ñìûñëà êàæäûé ðàç ÷èòàòü èç êîíôèãîâ, êîãäà äîñòàòî÷íî 1 ðàç çàïèñàòü â òàáëèöó
local ini = ini_file or system_ini()
if ltxExist(sec, line, ini) then
if mode==nil or mode=="numf" then --> ÷èñëî ñ çàïÿòîé
ltxBuffer[sec][line] = ini:r_float(sec, line)
return ltxBuffer[sec][line]
end
if mode=="bol" then --> true\false
ltxBuffer[sec][line] = ini:r_bool(sec, line)
return ltxBuffer[sec][line]
end
if mode=="num" then --> öåëîå ÷èñëî
ltxBuffer[sec][line] = ini:r_u32(sec, line)
return ltxBuffer[sec][line]
end
if mode=="str" then --> ñòðîêà
ltxBuffer[sec][line] = ini:r_string(sec, line)
return ltxBuffer[sec][line]
end
if mode=="vec" then --> âåêòîð
local vec = ini:r_vector(sec, line)
ltxBuffer[sec][line] = vec
--return ltxBuffer[sec][line] --> ÒÀÊ ÍÅ ÄÅËÀÒÜ
return utils.vector_copy_by_val(ltxBuffer[sec][line])
end
if mode=="tbl1" then --> òàáëèöà èç ñòðîêè ñ çàïÿòûìè (1 = ..., 2 = ....)
local temp = ini:r_string(sec, line)
ltxBuffer[sec][line] = string_expl(temp, ",")
return ltxBuffer[sec][line]
end
end
-- mDbg(_SN, "ltx - no section: "..sec.." || "..line)
return nil
end
--\\ Ïîçâîëÿåò âûñòàâèòü çíà÷åíèå êàêîãî ëèáî èç çàãðóæåííûõ ïàðàìåòðîâ êîíôèãà
function ltxBufferW(sec, line, value)
if not ltxBuffer[sec] then
ltxBuffer[sec] = {}
end
ltxBuffer[sec][line] = value
end
--\\ Âîçâðàùàåò èìÿ è îïèñàíèå ïðåäìåòà
-- sec - ñåêöèÿ ïðåäìåòà â êîíôèãàõ
function ltxItem(sec)
local name = ltx(sec, "inv_name", "str") or ""
local descr = ltx(sec, "description", "str") or ""
return xml(name), xml(descr)
end
--\\ Ïðîâåðÿåò, ÷òî òàêàÿ êîìáèíàöèÿ ñåêöèè-*ñòðîêè ñóùåñòâóåò â êîíôèãå
-- sec - ñåêöèÿ
-- *line - ñòðîêà
-- *ini_file - ini-êîíôèã îòêóäà íàäî ÷èòàòü, ïî óìîë÷àíèþ ÷èòàåò èç system.ltx è ïîäêë. ê íåìó ôàéëàõ
function ltxExist(sec, line, ini_file)
local ini = ini_file or system_ini()
if sec == nil then _abort(_SN, "ltxExist", "sec") end
if not ini:section_exist(sec) then return false end
if line and not ini:line_exist(sec, line) then return false end
printf("SWMtrue")
return true
end
--\\ Âîçâðàùàåò <text> èç òåêñòîâîãî xml-ôàéëà
-- xml_id - èäåíòèôèêàòîð òåêñòà
function xml(xml_id)
return game.translate_string(xml_id)
end
--\\ Ïðåîáðàçóåò òàáëèöó â îòôîðìàòèðîâàííóþ ñòðîêó äëÿ çàïèñè â custom data
--[[
local value = 123
local cd = {}
cd["test"] = {}
cd["test"]["string"] = ""
cd["test"]["line"] = value
cd["test"]["simple_table"] = {2,4,6,8}
cd["test"]["extended_table"] = {val1 = 1, val2 = 2, val3 = 3}
[test]
string
line = 123
simple_table = 2468
extended_table = val1, 1, val2, 2, val3, 3
]]
function tocdata(tTbl)
local result = ""
for sec, tData in pairs(tTbl) do
result = result.."\n["..sec.."]\n"
if type(tData) ~= "table" then
_abort(_SN, "tocdata", "tData is not table! result = %s, tData = %s", result, tostring(tData))
else
for line, t_Param in pairs(tData) do
if t_Param == "" then
result = result..tostring(line).."\n"
else
result = result..tostring(line).." = "
if type(t_Param) == "table" then
if table_size(t_Param) > 0 and #t_Param > 0 then
--* Ñêîðåå âñåãî ýòî íóìåðîâàííàÿ òàáëèöà, ïàêóåì å¸ áåç êëþ÷à
for _,p1 in pairs(t_Param) do
local first = true
if first then
result = result..tostring(p1)
first = false
else
result = result..", "..tostring(p1)
end
end
else
--* Õýø-òàáëèöà, å¸ ïèøåì âìåñòå ñ êëþ÷àìè
local first = true
for p1,p2 in pairs(t_Param) do
if first then
result = result..tostring(p1)..", "..tostring(p2)
first = false
else
result = result..", "..tostring(p1)..", "..tostring(p2)
end
end
end
result = result.."\n"
else
result = result..tostring(t_Param).."\n"
end
end
end
end
end
return result
end
--\\ Ñ÷èòûâàåò âñå ñòðîêè èç ñåêöèè â òàáëèöó âèäà ñòðîêà = çíà÷åíèå
function collect_sections(ini, sec)
local r = {}
if ini:section_exist(sec) then
local n = ini:line_count(sec)
if n > 0 then
for i = 0,n-1 do
local res,id,val = ini:r_line(sec,i,"","")
if r[id] == nil then
r[id] = val
end
end
end
end
return r
end
--\\ Êðýøíóòü èãðó ñ âûâîäîì â ëîã
function _abort(script_name, function_name, error_string, ...)
if script_name == nil then
script_name = "<nil>"
end
if function_name == nil then
function_name = "<nil>"
end
abort("%s.%s - "..error_string, script_name, function_name, ...)
end
--\\ Âûâîä â ëîã
function log(text)
if _console == nil or (_console.GetVal("dbg.log") == true) then
get_console():execute("load ~~ " .. tostring(text))
end
end
--\\ Ïîäñ÷¸ò êîë-âà ýëåìåíòîâ â òàáëèöå (ïîä-òàáëèöû ñ÷èòàåò çà 1 ýëåìåíò)
function table_size(tTbl)
local count = 0
for _,_ in pairs(tTbl) do
count = count + 1
end
return count
end
--! Âíèìàíèå: ñòàíäàðòíûé øàáëîí ïëîõî ðàáîòàåò ñ "îñîáûìè" ñèìâîëàìè (íàïðèìåð #) è ðàçáèâàåò ñòðîêó êðèâî
function string_expl(sStr, sDiv, Mode, bNoClear)
sStr = tostring(sStr)
if not (sStr ~= "nil" and sStr ~= '') then return {} end --> íå÷åãî ðàçäåëÿòü
local tRet = {}
local sPattern = '[%w%_]+' --> äåôîëòíûé ïàòåðí (ðàçäåëåíèå ïî 'ñëîâàì')
if type(sDiv) == "string" then --> åñëè çàäàí ñåïàðàòîð: ðàçäåëÿåì ïî íåìó
if bNoClear then --> åñëè ÍÅ óêàçàíî '÷èñòèòü ïðîáåëû'
sPattern = '([^'..sDiv..']+)'
else --> èíà÷å ñ ÷èñòêîé ïðîáåëîâ
sPattern = '%s*([^'..sDiv..']+)%s*'
end
end
--* ðàçäåëÿåì ñòðîêó ïî ïàòåðíó
if Mode == nil then --> îáû÷íûé ìàññèâ
for sValue in sStr:gmatch(sPattern) do
table.insert(tRet, sValue)
end
else
local sTypeMode = type(Mode)
if sTypeMode == "boolean" then --> òàáëèöà '[çíà÷åíèå] = true èëè false'
for sValue in sStr:gmatch(sPattern) do
tRet[sValue] = Mode
end
elseif sTypeMode == "number" then --> òàáëèöà '[idx] = ÷èñëî èëè ñòðèíã'
for sValue in sStr:gmatch(sPattern) do
tRet[#tRet+1] = tonumber(sValue) or sValue
end
end
end
return tRet --> âîçâðàùàåì òàáëèöó
end
--* Ðàñ÷¸ò ðàçíèöû ìåæäó äâóìÿ cam_dir:getH()
-- Äà, ó ìåíÿ ïëîõî ñ âåêòîðíîé àëãåáðîé î_Î
function calc_Y(new, old)
local wL = 0
local wR = 0
if new < old then
wR = old - new
if new < 0 then
wL = math.abs(-1.6 - new) + (4.8 - old)
else
wL = new + 1.6 + (4.8 - old)
end
else
wL = new - old
if old < 0 then
wR = (4.8 - new) + math.abs(-1.6 - old)
else
wR = (4.8 - new) + math.abs(-1.6) + old
end
end
if wL < wR then
return wL
end
if wL > wR then
return -wR
end
return 0
end
-- Âûäåëåíèå èç ìàòðèöû óãëîâ ïîâîðîòà â ïîñëåäîâàòåëüíîñòè x,z,y (P,B,H)
-- ïîäðàçóìåâàåòñÿ, ÷òî ìàòðèöà ÿâëÿåòñÿ ïðàâèëüíîé ìàòðèöåé ïîâîðîòà
-- ôóíêöèÿ ñîäðàíà èç áèáëèîòåêè Wild Magic 5
function extract_euler_xzy(m)
if m.i.y < 1 then
if m.i.y > -1 then
local az = math.asin(-m.i.y)
local ax = math.atan2(m.k.y, m.j.y)
local ay = math.atan2(m.i.z, m.i.x)
return ax, az, ay
else
local az = math.pi / 2
local ax = -math.atan2(-m.k.x, m.k.z)
local ay = 0
return ax, az, ay
end
else
local az = -math.pi / 2
local ax = math.atan2(-m.k.x, m.k.z)
local ay = 0
return ax, az, ay
end
end
function extract_direction(ph_element)
local m = ph_element:global_transform()
local p,b,h = extract_euler_xzy(m)
return vector():setHP(h, p)
end
--\\ Óçíà¸ì êàðòó, íà êîòîðîé íàõîäèòñÿ îáúåêò ïî ID\Server OBJ
function getMapName(id_or_sobj)
local sobj
if type(id_or_sobj) == "number" then
sobj = alife():object(id_or_sobj)
else
sobj = id_or_sobj
end
if sobj then
local lvert = game_graph():vertex(sobj.m_game_vertex_id)
local lid = lvert:level_id()
if lid ~= nil then
return alife():level_name(lid)
end
end
end
--\\ Óçíà¸ì ðàíã íåïèñÿ (âîçâðàùÿåò íîìåð ðàíãà, ðàíê (÷èñëî) è íàçâàíèå ðàíãà)
local rang_num_to_name = {
[0] = "st_rang_zero",
[1] = "st_rang_novice",
[2] = "st_rang_experienced",
[3] = "st_rang_experienced",
[4] = "st_rang_veteran",
[5] = "st_rang_master",
}
function rang(obj)
local rank = 0
local obj_rank = obj:rank()
if obj_rank >=0 and obj_rank <=25 then --> novice
rank = 1
end
if obj_rank >=26 and obj_rank <=30 then --> ext 1
rank = 2
end
if obj_rank >=31 and obj_rank <=40 then --> ext 2
rank = 3
end
if obj_rank >=41 and obj_rank <=50 then --> veteran
rank = 4
end
if obj_rank >=51 then --> master
rank = 5
end
--[[ CS 1.5.10
if obj_rank >= 0 and obj_rank <= 300 then
rank = 1 -- Novice
end
if obj_rank > 300 and obj_rank <= 450 then
rank = 2 -- Extnd. 1
end
if obj_rank > 450 and obj_rank <= 600 then
rank = 3 -- Extnd. 2
end
if obj_rank > 600 and obj_rank < 900 then
rank = 4 -- Veteran
end
if obj_rank >= 900 then
rank = 5 -- Master
end
]]
return rank, obj_rank, rang_num_to_name[rank]
end