Gość Diegtiariow Opublikowano 14 Stycznia 2023 Zgłoś Udostępnij Opublikowano 14 Stycznia 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 Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
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.