Jump to content

Przydatne funkcje dla skryptów Stalkera


Guest Diegtiariow

Recommended Posts

Guest Diegtiariow

Nazwa: Przydatne funkcje dla skryptów Stalkera
Twórca: liner

 

OPIS:

Spoiler

W tym temacie jest wiele przydatnych wg autora - funkcji (dla Lua), które zostały napisane przez innych ludzi.
Wersja Lua w Stalkerze - 5.1. Wszystkie funkcje zostały napisane na tą wersję.

Jeśli wykorzystujecie materiał, to autor prosi, abyście nie usuwali copywrite'ów i zostawiali podziękowania autor-owi/-am, bo to elementarna etyka modowania!

 

FUNKCJE:

Spoiler

Czy NPC ma podane przedmioty (w sekcji) has_items:

Spoiler

Platformy: СS, CoP
Autor: liner

--Czy NPC ma podane przedmioty?
--ilość przedmiotów nie jest ograniczona

function has_items(npc,...) --sekcje przedmiotów
    local t = {...}
    local function calc(q,itm)
        local sect = itm:section()
        for k,v in pairs(t) do
            if sect == v then
                v = nil
                return
            end
        end
    end
    npc:iterate_inventory(calc)
    return table.getn(t) == 0 --wszystkie elementy tablicy powinny być nil
end

Jak używać:

has_items(db.actor,"medkit","bandage","wpn_pm")                   <CAI_Stalker*, ...<string>>

 

Usunięcie z inwentarza NPC kilku przedmiotów remove_item_count:

Spoiler

Platformy: SoC (z wątpliwościami), CS, CoP
Autor: Suhar_
Funkcja usuwa z inwetarza NPC kilka przedmiotów

function remove_item_count(who, item_section, count)
    local current_count = count
    local function remove(tmp, item)
        if item:section()==item_section and (current_count>0) then
            current_count = current_count - 1
            -- Przechodzimy z obiektu w grze do obiektu serwerowego poprzez jego ID
            -- Usuwamy serwerowy obiekt
            alife():release(alife():object(item:id()), true)
        elseif current_count<=0 then
            return
        end
    end
    who:iterate_inventory(remove)
end

Jak używać:

remove_item_count(npc_lub_aktor, sekcja_przedmiotu_który_zostanie_usunięty, ile_sztuk_usunąć)
<CGameObject*,string,number>

 

Analogia do silnikowego READ_IF_EXISTS:

Spoiler

Platformy: SoC, CS, CoP
Autor: liner
Przeczytać z sekcji w jakimś pliku linijkę i jeśli tej linijki/sekcji nie ma, przywrócić domyślną wartość, którą ustawia użytkownik. W przeciwnym razie funkcja przywróci to, co przeczytała z sekcji.

UWAGA!!! DO TEJ FUNKCJI TRZEBA ZAIMPLEMENTOWAĆ FUNKCJĘ toboolean. JEST W TYM TEMACIE!!!

function READ_EX(r_type,sect,what,default_val,ini)
    if not ini then
        ini = system_ini()
    end
    if not ini:section_exist(sect) or not ini:line_exist(sect,what) then
        return default_val
    end --jeśli do tego miejsca, to są niezbędne parametry
    if r_type == "number" then
        return ini:r_u32(sect,what)
    elseif r_type == "string" then
        return ini:r_string(sect,what)
    elseif r_type == "float" then
        return ini:r_float(sect,what)
    elseif r_type == "bool" then
        return toboolean(ini:r_string(sect,what))
    elseif r_type == "s32" then
        return ini:r_s32(sect,what)
    else
        return nil
    end
end

Jak używać:
                                                                                                            (NIEOBOWIĄZKOWO)             (NIEOBOWIĄZKOWO)

READ_EX(typ, czytanie, sekcja, jaką_linijkę_przeczytać, wartość_domyślna, plik_z_którego_będziemy_czytać)
<string,string,string,any,CIniFile*>
READ_EX("float", "damage_head_40", "bip01_neck", 0.5) --Jeśli w sekcji damage_head_40 jest linijka bip01_neck, to funkcja przywróci wartość tej linijki, w przeciwnym wypadku podana wartość domyślna to 0.5

 

 

Ustalenie liczby między dwoma zakresami clamp:

Spoiler

Platformy: SoC, CS, CoP
Autor: liner
Ustalenie liczby między dwoma zakresami
Jeśli wartość przekracza przedział, to ta liczba staje się minimalną liczbą zakresu (lub jeśli byłaby ona mniejsza od minimum i odpowiednio maksimum - jeśli liczba przekracza maksimum).

function clamp(value, min, max)
    if min ~= nil and value<min then
        return min
    elseif max ~= nil and value>max then
        return max
    end
    return value
end

Jak używać:

clamp(liczba, minimum (nieobowiązkowo), maksimum (nieobowiązkowo))          <number,number,number>
clamp(7.7, 6.02, 7.5)          --output: 7.5
clamp(14,15,16)                 --output: 15
clamp(0,8)                           --output: 8
clamp(-3,nil,-5)                    --output: -5

 

Wyświetlenie tekstu nad środkiem ekranu z określonym czasem zniknięcia HudMsg:

Spoiler

Platformy: SoC (z wątpliwościami), CS, CoP
Autor: makdm, liner
Wyświetlenie tekstu nad środkiem ekranu z określonym czasem zniknięcia

local a_show = true
function HudMsg(text_center, sTime) --Copyright makdm, liner
    if sTime == nil then sTime = 5 end
    local hud = get_hud()
    local timer_text = time_global() + sTime*1000
    if a_show == true then
        a_show = false
        hud:HideActorMenu()
        local cs_text = hud:GetCustomStatic("not_enough_money_mine")
        if cs_text then
            hud:RemoveCustomStatic("not_enough_money_mine")
        end
        hud:AddCustomStatic("not_enough_money_mine", true)
        cs_text = hud:GetCustomStatic("not_enough_money_mine")
        cs_text:wnd():TextControl():SetText(game.translate_string(text_center))
        level.add_call(
            function ()
            if timer_text < time_global() then
                return true
            end
            end,
            function ()
                hud:RemoveCustomStatic("not_enough_money_mine")
                a_show = true
            end
        )
    end
end

Jak używać:

HudMsg(string_id_tekstu_który_trzeba_wyświetlić, czas_wyświetlania_w_sekundach)         <string,number>

 

Wydanie przedmiot-u/-ów graczowi give_item:

Spoiler

Platformy: SoC, CS, CoP
Autor: liner

function give_item(sect,count)
    if count==nil or count == 1 then
        return alife():create(sect,db.actor:position(),db.actor:level_vertex_id(),db.actor:game_vertex_id(),ACT_ID)
    else
        local act = db.actor
        local pos,lv,gv,id = act:position(),act:level_vertex_id(),act:game_vertex_id(),act:id()
        for i=1, count do
            alife():create(sect,pos,lv,gv,id)
        end
    end
end

Jak używać:

give_item(sekcja_przedmiotu, ilość_do_zespawnowania (nieobowiązkowo, domyślnie 1))      <string,number>

 

Wywołanie kodu lua z pomocą linijki LOADVOID:

Spoiler

Platformy: SoC, CS, CoP
Autor: liner

Dana funkcja pozwala wykonać funkcję z jakiegoś skryptu. Jest to rzeczywiście bardzo potrzebna funkcja.

function LOADVOID(funct, ...)
    return loadstring(tostring(funct))(...)
end

Jak używać:

LOADVOID(nazwa_funkcji, argumenty_które_trzeba_przesłać_do_funkcji (NIEOBOWIĄZKOWO))   <string, any>
LOADVOID("sim_squad_scripted.init()", true)          --odpowiednik kodu: sim_squad_scripted.init(true)

 

Dodanie spotu/punktu na obiekt add_spot_on_map:

Spoiler

Platformy: CS, CoP
Autor: Suhar_
Dodanie znacznika na obiekt poprzez jego ID na mapę (PDA i/lub minimapę, zależy od ustawień spotu)

function add_spot_on_map(obj_id, location_name, descr)
    if level.map_has_object_spot(obj_id,location_name)==0 then
        if descr==nil then
            descr=""
        end
        level.map_add_object_spot_ser(obj_id, location_name, descr)
    end
end

Jak używać:

add_spot_on_map(ID obiektu, nazwa_punktu, opis_punktu (nieobowiązkowo))           <number,string,string>
add_spot_on_map(3280, "alife_secondary_presentation_stalker", game.translate_string("st_squad_spot_descr"))

 

Obliczanie ilości znaków w linijce calc_symbols:

Spoiler

Platformy: SoC, CS, CoP
Autor: liner

Obliczanie ilości znaków w linijce

function calc_symbols(str,symbol)
    local n = 0
    for s in str:gmatch(symbol) do
        n = n + 1
    end
    return n
end

Jak używać:

calc_symbols(tekst, znaki_w_tekście_które_chcemy_zliczyć)          <string,string>
calc_symbols("abc inferno base", "a")                   --output: 2

 

Przekonwertowanie argumentu do typu boolean toboolean:

Spoiler

Platformy: SoC, CS, CoP
Autor: liner
Przekonwertowanie argumentu do typu boolean (true lub false).
UWAGA!!! DO TEJ FUNKCJI TRZEBA ZAIMPLEMENTOWAĆ FUNKCJĘ string.filter. JEST ONA W TYM TEMACIE!!!

function toboolean(arg)
    if arg ~= nil then
        if type(arg) == "string" then
            arg = string.filter(arg) --usuwamy wszystkie odstępy i spacje z linijki
        end
        if arg=="true" or tonumber(arg) == 1 or arg == "on" or arg == true then return true end
        if arg=="false" or tonumber(arg) == 0 or arg == "off" or arg == false then return false end
    end
    return nil
end

Jak używać:

toboolean(dowolny argument typu bool lub number lub string)
toboolean(1)        --output: true
toboolean("0")     --output: false
toboolean(nil)      --output: nil

 

Analiza linijki przez klucz "," (przecinek) parse_by_comma:

Spoiler

Platformy: SoC, CS, CoP
Autor: Suhar_

Analiza linijki przez symbol "," (przecinek)

UWAGA!!! DO TEJ FUNKCJI TRZEBA ZAIMPLEMENTOWAĆ FUNKCJĘ string.explode. JEST ONA W TYM TEMACIE!!!

function parse_by_comma(s)
    s = string.gsub(s," ", "") --usuwamy spacje
    s = string.gsub(s,"    ", "") --usuwamy tabulacje
    s = string.explode(",", s, false)
    return s
end

Jak używać:

parse_by_comma(tekst)          <string>
parse_by_comma("s,u,b,b")       --output: tablica w postaci
--{
--    [1] = "s",
--    [2] = "u",
--    [3] = "b",
--    [4] = "b"
--}

 

 

Rozbijanie linijki na elementy string.explode:

Spoiler

Platformy: SoC, CS, CoP
Autor: Bak
Rozbijanie linijki na elementy z pomocą specjalnego klucza

UWAGA!!! DO TEJ FUNKCJI TRZEBA ZAIMPLEMENTOWAĆ FUNKCJĘ trim. JEST ONA W TYM TEMACIE!!!

function string.explode(div,str,clear)
    local t={}
    local cpt = string.find(str,div,1,true)
    if cpt then
        repeat
            if clear then
                table.insert(t,trim(string.sub(str,1,cpt-1)))
            else
                table.insert(t,string.sub(str,1,cpt-1))
            end
            str = string.sub(str,cpt+string.len(div))
            cpt = string.find(str,div,1,true)
        until cpt==nil
    end
    if clear then
        table.insert(t,trim(str))
    else
        table.insert(t,str)
    end
    return t
end

Jak używać:

string.explode(specjalny klucz, linijka, czy boolean używa funkcji trim)     <string,string,boolean>
string.explode("$", "el1$el2$el3&&@#&@&$null")          --output: tablica w postaci
--{
--   [1] = "el1",
--   [2] = "el2",
--   [3] = "el3&&@#&@&",
--   [4] = "null"
--}

 

Usuwanie spacji na początku i na końcu linijki trim:

Spoiler

Platformy: SoC, CS, CoP
Autor: ??? (nieznany)

Usunięcie spacji na początku i końcu linijki

function trim(s)
    return(string.gsub(s,"^%s*(.-)%s*$","%1"))
end

Jak wywołać:

trim(tekst)                      <string>
trim(" aboltus   !   ")         --output:aboltus   !

 

Średnia arytmetyczna liczb math.avr:

Spoiler

Autor funkcji: liner
Platformy: SoC, CS, CoP
Średnia arytmetyczna liczb (sr = a1 + a2+ a3 +... : n, gdzie n - ilość liczb)

function math.avr(...)
    local t = {...}
    local sum = 0
    for _,v in pairs(t) do
        sum = sum + v
    end
    return sum / #t
end

Jak używać:

math.avr(dowolne liczby)                     <number>
math.avr(3, 5, 18, 30) --output: 14

 

Otrzymanie typu danych argumentu typeid:

Spoiler

Platformy: SoC, CS, CoP
Autor: liner

Otrzymanie typu danych argumentu. Uwaga! Zwracany typ danych zależy OD WARTOŚCI LICZBY!!!
UWAGA!!! FUNKCJA MA JEDEN ZNACZĄCY MINUS: FUNKCJA NIGDY NIE ZWRÓCI "<float>", DLATEGO ŻE TWÓRCA NIE WIE, JAK TO ZROBIĆ BEZ math.type (a ta funkcja jest z wersji Lua 5.3)!

function typeid(arg)
    local t = type(arg)
    if t == "string" then
        return "<string>"
    elseif t == "boolean" then
        return "<bool>"
    elseif t == "number" then
--liner: available since version Lua 5.3 ((
--        if math.type(arg) == "float" then
--            return "<float>"
--        end
        --unsigned integer
        if arg >= 0 then
            if arg <= 255 then
                return "<u8>"
            elseif arg <= 65535 then
                return "<u16>"
            elseif arg <= 4294967295 then
                return "<u32>"
            end
        --signed integer
        elseif arg >= -2147483648 and arg < -32768 then
            return "<s32>"
        elseif arg >= -32768 and arg < -128 then
            return "<s16>"
        elseif arg >= -128 then
            return "<s8>"
        end
    elseif t == "table" then
        return "<table>"
    elseif t == "userdata" then
        return "<object>"
    end
    return "<undefined>" --default
end

Jak używać:

typeid(dowolny jeden argument)
typeid(7)                 --output: <u8>
typeid(256)            --output: <u16>
typeid({1234, 2458, "sl"})            --output: <table>
I tak dalej...

 

Złożone wywołanie funkcji cws_call:

Spoiler

Autor: liner
Platformy: SoC (z wątpliwościami), CS, CoP

Złożone wywołanie funkcji z dodatkowymi argumentami dla funkcji (pełna nazwa: complex call with settings). Dana funkcja wywołuje przekazaną funkcję kilka razy z argumentami, które zostały przekazane w ... i przekazuje jeszcze dodatkowo do wszystkich funkcji argumenty z ustawienia_transferu.

_cjm = "`" --Ta zmienna musi być zadeklarowana w _G, jeśli cws_call jest wykorzystywana wszędzie.
function cws_call(funct,settings,...)
    local t = {...}
    local s_size = #settings --cachujemy rozmiar tablicy
    local lst = 1
    for i = 1, #t do
        if t == _cjm then
            local ct = {}
            for j = lst, i-1 do
                table.insert(ct,t[j])
            end
            for j = 1, s_size do
                table.insert(ct,settings[j])
            end
            lst = i + 1
            funct(select(1,unpack(ct)))
        end
    end
    local ct = {select(lst,...)}
    for j = 1, s_size do
        table.insert(ct,settings[j])
    end
    funct(select(1,unpack(ct)))
end

Jak używać:

cws_call(link do funkcji,{ustawienia_transferu},argumenty)               <function, table, ...>
cws_call(print,{"THIRD ARGUMENT","end"}, 1,_cjm,"GO!",0,0)

Gdzie_cjm - separator, przed nim wszystkie argumenty zostaną przekazane do funkcji (w tym przypadku to print)

Poprzedni cws_call jest równoważny kodowi:

print(1,"THIRD ARGUMENT","end")
print("GO!",0,0,"THIRD ARGUMENT","end")

 

Usunięcie wszystkich tabulacji i spacji w linijce string.filter:

Spoiler

Autor: Suhar_

string.filter = function (str)
    str = string.gsub(str, " ", "") --spacje
    str = string.gsub(str, "    ", "") --tabulacje
    return str
end

 

Wydanie przedmiotu/-ów podczas używania przedmiotu:

Spoiler

Autor: liner
Platformy: SoC, CS, CoP
UWAGA! ABY KOD DZIAŁAŁ POTRZEBNA JEST FUNKCJA parse_by_comma. JEST ONA W TYM TEMACIE!
Opis: przez skrypt wydać kilka przedmiotów podczas używania przedmiotu.

Aby ten skrypt zadziałał, potrzebujesz:
1. Skopiowania tego bloku kodu:

--Tworzenie przedmiotów dla aktora
	--Trzeba dawać w takiej postaci:
	--give = medkit,2,bandage,1 (dwie apteczki, jeden bandaż)
	--lub
	--give = medkit,bandage (jedna apteczka, jeden bandaż)
	--jedynki nie trzeba pisać.
	local sect = obj:section()
	if system_ini():line_exist(sect,"give") then
		local p = parse_by_comma(system_ini():r_string(sect,"give"))
		local t_items = {}
		for i = 1, #p do
			if not tonumber(p[i]) then
				t_items[i] = {p[i],tonumber(p[i+1]) or 1}
			end
		end
		local pos, lvid, gvid, sim = db.actor:position(),db.actor:level_vertex_id(),db.actor:game_vertex_id(), alife()
		for i,v in pairs(t_items) do
			for j = 1, v[2] do
				sim:create(v[1],pos,lvid,gvid,0)
			end
		end
	end

2. Wstawić do skryptu bind_stalker do metody use_inventory_item na sam koniec bloku kodu (przed ostatnim end) skopiowany kod
3. W konfigu napisać potrzebne parametry. Np, dla testów twórca robił:
W sekcji [medkit] napisano następujące:
NA DOLE SKŁADNIA
give = bandage, 2
Wydało mi dwa bandaże.
give = bandage,antirad,wpn_pm
Wydało mi: bandaż, antyrad, i PM.

Jeśli chcesz żeby wydało jeden przedmiot, to jedynki możesz nie pisać. Ilość przedmiotów zawsze jest pisana po nazwie przedmiotu.

 

 

ŹRÓDŁO:

ap-pro.ru

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.