Skocz do zawartości

Przydatne funkcje dla skryptów Stalkera


Gość Diegtiariow

Rekomendowane odpowiedzi

Gość 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

Odnośnik do komentarza
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.
Uwaga: Twój wpis zanim będzie widoczny, będzie wymagał zatwierdzenia moderatora.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Korzystając z tej strony, zgadzasz się na nasze Warunki użytkowania.