Guest Diegtiariow Posted January 14, 2023 Report Share Posted January 14, 2023 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 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.