Gość Diegtiariow Opublikowano 26 Lutego 2023 Zgłoś Udostępnij Opublikowano 26 Lutego 2023 OPIS: W danym temacie zebrano informacje na temat skryptowego modelu stalkera: funkcje i klasy, metody i właściwości, powiązanie i kolejność pracy z nimi, zależności pracy klas i plików konfiguracji. Każdy jest mile widziany do współtworzenia tematu. Następujące osoby uczestniczyły w aktualizacji infomacji w temacie: Monnoroch, Kolmogor, Unnamed Black Wolf, меченый (стрелок), IQDDD, Kirag, Taroz, dan, lekzd, 7.9, Garry_Galler, AKKK1, Bak i wiele innych osób. KLASA ALIFE_SIMULATOR. PODSTAWOWE OPERACJE Z SERWEROWYMI OBIEKTAMI: Spoiler Klasa jest potrzebna do wykonania podstawowych zadań po stronie serwera: tworzenie i usuwanie obiektów, szukanie obiektów po identyfikatorach, przejście w tryb online/offline, sprawdzanie infoportion. Z tego szeregu dziwnym sposobem wydostaje się otrzymanie numeru aktualnego poziomu. Obiekt takiej klasy jest jeden i może zostać otrzymany globalną funkcją alife(). Używamy przykładowo tak: local sim = alife() -- otrzymujemy sam obiekt klasy alife_simulator local sactor = sim:actor() -- otrzymujemy serwerowy obiekt dla aktora Opis formalny: class alife_simulator { float switch_distance(); // otrzymanie odległości przełączenia online/offline void switch_distance(float dist); // ustawić odległość. Nie działa! int level_id(); // numer obecnego poziomu string level_name(int level_id) // zwraca nazwę poziomu po jego id cse_abstract* create(string <nazwa sekcji obiektu>, vector* position, int level_vertex_id, int game_vertex_id) // tworzenie obiektów na poziomie cse_abstract* create(string <nazwa sekcji obiektu>, vector* position, int level_vertex_id, int game_vertex_id, int parent_id) // tworzenie obiektów w inwentarzu cse_abstract* create_ammo(string <nazwa sekcji nabojów>, vector* position, int level_vertex_id, int game_vertex_id, int parent_id, int amount) // tworzenie paczek z nabojami cse_alife_dynamic_object* create(int <indeks obiektu w all.spawn> ) // tworzenie obiektu na podstawie sekcji w all.spawn int spawn_id(int id) // indeks sekcji w all.spawn dla obiektu z zadanym id void release(cse_abstract* obj, bool); // usunięcie obiektu. cse_alife_dynamic_object* object(int id, bool no_assert); // otrzymanie obiektu po id. cse_alife_dynamic_object* object(int id); // równoważne poprzedniej funkcji z no_assert == true. cse_alife_dynamic_object* object(string name); // otrzymanie obiektu po nazwie. W ZP nie ma! cse_alife_dynamic_object* story_object(int story_id); // otrzymanie obiektu po fabularnemu identyfikatorowi cse_alife_creature_actor* actor(); // otrzymanie serwerowego obiektu aktora. Można i po prostu otrzymać go po id, równego 0 bool valid_object_id(int id); // sprawdza, czy argument nie jest równy 65535 (-1). Niezwykle bezużyteczna funkcja. void set_switch_online(int id, bool v); // ustawia flagę flSwitchOnline, która określa możliwość przejścia w online void set_switch_offline(int id, bool v); // ustawia flagę flSwitchOffline, która określa możliwość przejścia w offline void set_interactive(int id, bool v); // ustawia flagę flInteractive bool has_info(int id, string info_portion); // sprawdza dostępność infoportion bool dont_has_info(int id, string info_portion); // sprawdza brak infoportion void add_out_restriction(cse_alife_monster_abstract* obj, int restrictor_id); // ustawienie ograniczenia na wyjście void add_in_restriction(cse_alife_monster_abstract* obj, int restrictor_id); // ustawienie ograniczenia na wejście void remove_out_restriction(cse_alife_monster_abstract* obj, int restrictor_id); // zdjęcie ograniczenia na wyjście void remove_in_restriction(cse_alife_monster_abstract* obj, int restrictor_id); // zdjęcie ograniczenia na wejście void remove_all_restrictions(int object_id, const enum RestrictionSpace::ERestrictorTypes type); // zdjęcie wszystkich ograniczeń albo na wejście, albo na wyjście // Możliwe, że odpowiada za zabijanie w offline void kill_entity(cse_alife_monster_abstract* monster, int game_vertex_id, cse_alife_schedulable* obj); void kill_entity(cse_alife_monster_abstract* monster, int game_vertex_id); // równoważne pierwszej funkcji z obj == 0 void kill_entity(cse_alife_monster_abstract* monster); // równoważne drugiej z game_vertex_id, równym gvid potwora, przekazanego w pierwszym argumencie }; Komentarze do niektórych funkcji: Spoiler void switch_distance(float dist); - funkcja dla ustawienia zasięgu online. Może powodować wylot. Jednakże, ten promień można zmienić w pliku konfiguracji alife.ltx w sekcji [alife]. Jest tam parametr switch_distance. Również jest tam parametr histerezy przejścia switch_factor. string level_name(int level_id) - funkcja zwraca systemową nazwę poziomu, np. "L01_Escape" dla Kordona. W liście napisów dla wielu poziomów są zrozumiałe nazwy. Można je otrzymać w taki sposób: local level_name = game.translate_string(string.lower(alife():level_name(level_id))) Funkcja create z argumentem parent_id pozwala na tworzenie tylko ekwipunkowych przedmiotów. Argument amount funkcji create_ammo ustawia ilość nabojów w paczce. Paczka zawsze tworzona jest jedna. Numer sekcji w pliku all.spawn dla funkcji create z jednym argumentem i spawn_id - to po prostu numer porządkowy pozycji obiektu w all.spawn. Ma tendencję do zmian po przepakowaniu z pomocą acdc. Funkcje create zwracają stworzony obiekt. Jednakże jest on sprowadzony do typu cse_abstract, i nie są możliwe z nim wszystkie operacje. Lepiej po stworzeniu obiektu otrzymać obiekt ponownie, korzystając z jednej z funkcji szukania obiektów. Z funkcją release lepiej być ostrożnym. Niektóre obiekty przed usunięciem, trzeba przenosić do offline. Drugi boolowski argument tej funkcji jest ignorowany. Funkcje set_switch_online, set_switch_offline i set_interactive pozwalają na zmianę odpowiednich flag z pola object_flags. Flagi flSwitchOnline i flSwitchOffline czasami są sprawdzane dla każdego obiektu i określają możliwość przejścia w online lub offline odpowiednio. Jeśli oba są true, to obiekt będzie przechodzić w online/offline automatycznie po przekroczeniu promienia online. Kombinacje true/false i false/true odpowiednio wymuszają jeden ze stanów niezależnie od odległości do aktora. Oczywiście to wszystko ma znaczenie przy znalezieniu obiektu na jednym poziomie z aktorem. Dla niektórych obiektów, sprawdzanie jest wykonywana nie przez te flagi, a przez funkcje can_switch_online i can_switch_offline, które trzeba przeładować w skryptowej serwerowej klasie i takim sposobem sterować przełączaniem. Właściwie dla pozostałych obiektów, sterowanie również jest realizowane przez te funkcje. Domyślnie zwracają wartości tych flag. Z flagą flInteractive nie eksperymentowano, a wyjaśniono, że funkcja interactive zwraca true, jeśli są ustawione w 1 trzy flagi: flInteractive, flVisibleForAI i flUsefulForAI. To ma sens dla NPC, ale jaki dokładnie - niewiadomo. W funkcjach dla sterowania ograniczeniami trzeba przekazać id restryktorów. Restryktory mają własne pole typu, ale (według twórcy posta na AMK) w tych funkcjach jest ignorowany własny typ restryktora. W funkcji remove_all_restrictions drugi argument type określa, jakie dokładnie ograniczenia trzeba usunąć. Dopuszczalne wartości dla tej funkcji: 4 - in, 5 - out. Więcej o typach restryktorów: Spoiler Jest ich 6, co określa się takim wyliczeniem: enum RestrictionSpace::ERestrictorTypes { eDefaultRestrictorTypeNone, // 0 eDefaultRestrictorTypeOut, // 1 eDefaultRestrictorTypeIn, // 2 eRestrictorTypeNone, // 3 eRestrictorTypeIn, // 4 eRestrictorTypeOut, // 5 }; Można zwrócić uwagę, że w all.spawn nigdy nie ma restryktorów z 4 i 5. Nie ma też 1. Ogólnie można przyjąć kilka założeń: - typ restryktora 0 lub 3 - to jakby w ogóle "nie restryktor" i jest wykorzystywany głównie dla skryptowych stref, gdzie silnik za nic nie odpowiada, a wszystkie sprawdzenia są wykonywane przez skrypty. - tylko typy restryktora 1 i 2 mają sens dla silnika i najwyraźniej prowadzą do powstania stref "gdzie wszyscy nie chodzą" - strefy "skąd dla wszystkich nie ma drogi" ewidentnie są bez znaczenia, dlatego i nie jest spotykany typ 1 - odnośnie typów 4 i 5 - wynika z tego, że to nie są typy restryktorów, a specjalne stałe dla funkcji. Dlaczego zostały umieszczone w tym wyliczeniu, nie wiadomo. Ponownie wygląda to tak, że można używać restryktorów z dowolnym typem (ponieważ ich typ nie jest sprawdzany). Zwróćcie także uwagę, że klasa game_object ma funkcje, również odpowiadające za sterowanie ograniczeniami. Cel wszystkich wariantów funkcji kill_entity jest niejasny. Niby odpowiadają za zabijanie w offline, ale powodują wylot. PRZESTRZENIE NAZW. GLOBALNE FUNKCJE DLA DUŻEJ LICZBY ZADAŃ: Spoiler WSTĘP: Spoiler Globalne funkcje lub inaczej - funkcje z przestrzeni nazw. Taka funkcja może zostać użyta w dowolnym miejscu w następujący sposób: <przestrzeń nazw>.<nazwa funkcji>(<lista argumentów>) Przestrzeń nazw - to tylko sposób grupowania funkcji na jakiejś podstawie. Chociaż warto zauważyć, że logika grupowania funkcji w stalkerze czasami nie daje się wyjaśnić. W sumie jest kilka przestrzeń nazw: bez nazwy (tzn. funkcje z tej przestrzeni są wywoływane po prostu po nazwach jak zwykłe globalne funkcje), game, level, relation_registry, actor_stats. W Czystym Niebie (i ZP) pojawiła się przestrzeń nazw main_menu, oprócz tego są małe zmiany w pozostałych: niektóre funkcje zniknęły, niektóre zostały dodane. Zmiany są jednakże nieznaczące. Teraz rozpatrujemy tylko 3 podstawowe przestrzenie nazw (bez nazwy, game, level) i tylko dla Cienia Czarnobyla. PRZESTRZEŃ NAZW BEZ NAZWY: Spoiler Funkcje, które nie działają, powodują wyloty lub nieznany jest ich cel: function log(string) -- najprawdopodobniej dla wersji debug function error_log(string) -- najprawdopodobniej dla wersji debug function flush() -- najprawdopodobniej dla wersji debug bool app_ready() -- gotowość do czegoś ? póki gra jeszcze się nie wczytała zwraca false, po wczytaniu - true bool editor() -- czy edytor został odpalony??? int script_server_object_version() -- liczba możliwe, że coś oznacza function verify_if_thread_is_running() -- sprawdzanie, czy wątki są uruchomione/działają function xrRender_test_r2_hw() -- najprawdopodobniej funkcja testująca render 2 Otrzymanie niektórych globalnych obiektów: alife_simulator* alife() -- patrz opis alife_simulator render_device* device() -- patrz opis render_device CGameGraph* game_graph() -- otrzymanie globalnego grafu gry CConsole* get_console() -- otrzymanie obiektu dla sterowania konsolą CUIGameCustom* get_hud() -- otrzymanie obiektu do sterowania HUD'em. Można dodać do HUD'a swoje okienka i elementy sterowania. Tak działają wszystkie wskaźniki. FS* getFS() -- operacje na plikach. patrz opis FS string command_line() -- linijka na komendy łącznie z pełną ścieżką do wykonywanego pliku string user_name() -- sieciowa nazwa gracza (wydaje się nazwą aktywnego użytkownika w systemie) cef_storage* ef_storage() -- ??? Praca z plikami konfiguracji: ini_file* create_ini_file(string) -- tworzy z linijki obiekt typu ini_file w pamięci ini_file* game_ini() -- otwarty plik "config\game.ltx" i wszystkie jego załączniki ini_file* system_ini() -- otwarty plik "config\system.ltx" i wszystkie jego załączniki Operacje na bitach: function bit_and(number, number) -- AND function bit_not(number) -- NOT function bit_or(number, number) -- OR function bit_xor(number, number) -- XOR function dik_to_bind(number) -- prawdopodobnie konwertuje stałą z zestawu DIK_keys w stałą z zestawu key_bindings DWORD GetARGB(number, number, number, number) -- tworzy 32-bitową liczbę całkowitą z 4 oddzielnych bajtów. Dla ustawienia koloru. Różne małe rzeczy: void prefetch(string <nazwa modułu>) -- powoduje wczytanie i prekompilację modułu. Nazwa modułu jest określana bez rozszerzenia ".script" int time_global() -- czas rzeczywisty (w milisekundach) od początku uruchomienia programu void buy_condition(ini_file*, string <nazwa sekcji>) -- czyta ustawienia handlarza, na kupno z pliku konfiguracji i określonej sekcji. void buy_condition(float, float) -- tutaj prawdopodobnie chodzi o ceny, bo są dwa float'y (liczby zmiennoprzecinkowe) void sell_condition(ini_file*, string <nazwa sekcji>) -- analogicznie na sprzedaż void sell_condition(float, float) -- analogicznie jak wyżej w kupnie void show_condition(ini_file*, string <nazwa sekcji>) -- prawdopodobnie chodzi o umożliwienie sprzedaży/kupna po spełnieniu jakichś warunków, np. wyłączenie psi-instalacji, znalezienie dokumentów, itd. Dalej opisane funkcje umożliwiają konwersję wskaźnika do bazowej klasy na wskaźnik do klasy pochodnej w celu otrzymania dostępu do metod klasy pochodnej. Szczegółowe informacje znajdują się w opisie odpowiednich hierarchii: action_planner* cast_action_to_planner(action_base*) action_base* cast_planner_to_action(action_planner*) cse_alife_creature_abstract* cast_alife_object_to_creature(cse_alife_object*) cse_alife_trader_abstract* cast_alife_object_to_trader_abstract(cse_alife_object*) Otrzymanie wbudowanych czcionek: CGameFont* GetFontDI() CGameFont* GetFontGraffiti19Russian() CGameFont* GetFontGraffiti22Russian() CGameFont* GetFontGraffiti32Russian() CGameFont* GetFontGraffiti50Russian() CGameFont* GetFontLetterica16Russian() CGameFont* GetFontLetterica18Russian() CGameFont* GetFontLetterica25() CGameFont* GetFontMedium() CGameFont* GetFontSmall() Informacja o teksturach. W ZP te funkcje są usunięte: CGameFont* GetTextureInfo(string, string) CGameFont* GetTextureName(string) CGameFont* GetTextureRect(string) PRZESTRZEŃ NAZW GAME: Spoiler CTime* get_game_time() -- przywraca czas gry w postaci obiektu klasy CTime void start_tutorial(string) -- uruchamia tutorial, zarejestrowany w pliku ui\game_tutorials.xml. Na tutorialach zrobiono sny bool has_active_tutorial() -- czy jest uruchomiony tutorial int time() -- czas gry (w milisekundach czasu gry) od początku gry (tzn. od początku przechodzenia gry) string translate_string(string) -- otrzymuje prawidłową linijkę po identyfikatorze string z jednego z plików .xml, zapisanych w pliku \config\localization.ltx w sekcji [string_table] w parametrze files, jeśli tam nie ma takiej linijki, to zwraca swój argument - źródłową linijkę PRZESTRZEŃ NAZW LEVEL: Spoiler Funkcje nieokreślone lub powodujące niezrozumiałe wyloty: function check_object(game_object*)-- wygląda chytrze. Tak jakby istniało pole level.check_object i rodzaj jego "function", jednakże wartość tego pola nil i jego wywołanie nie jest możliwe. To znaczy takiej funkcji nie ma, widocznie była ona w wersji debug. function debug_actor() -- analogicznie check_object. Nie ma takiej funkcji function debug_object(string) -- analogicznie check_object. Nie ma takiej funkcji function physics_world() -- w SoC - wylot function environment() -- w SoC - wylot Wylotu nie powodują, ale cel nie jest znany: int game_id() -- zwraca jakąś liczbę. Prawdopodobnie dla multiplayera. client_spawn_manager* client_spawn_manager() -- zwraca jakiś obiekt, z pomocą którego można za pomocą którego możesz umieścić kilka callback'ów na spawnie. W grze nie jest nigdzie używany. Informacja o poziomie jako całości, zarządzanie poziomem: bool present() -- dostępność poziomu. Tak można określać, że gra została wczytana. To znaczy, że jeżeli jesteśmy w głównym menu i gra nie jest wczytana, to funkcja zwraca false string name() -- nazwa aktualnego poziomu, a dokładniej jego identyfikator Fbox* get_bounding_volume() -- daje rodzaj równoległościanu, najwyraźniej zakrywającego poziom Callback'i: void add_call(const function&, const function&)-- dodawane są dwa callbacki: - pierwszy. Brak argumentów, wywołuje się okresowo i natychmiast po aktualizacji aktora, powinien zwracać false do tej pory, aż nie zdecyduje się zakończyć pracy. - drugi. Brak argumentów, wywołuje się jeden raz, od razu po ostatnim wywołaniu pierwszego callbacka (po tym, jak ten zwróci true), ponieważ częstotliwość wywołań pokrywa się z aktualizacjami aktora, to można stwierdzić, że callback jest nakładany na aktora void remove_call(const function&, const function&) -- teoretycznie powinno usuwać callbacki, ale jakoś nie działa void add_call(object, const function&, const function&) -- analogicznie dla dowolnego obiektu, ale teraz jako pierwszy argument callbacka przy jego wywołaniu, jest przekazywany ten obiekt, na który go nałożyliśmy void remove_call(object, const function&, const function&) void add_call(object, string, string) -- nie wiadomo jak działa void remove_call(object, string, string) void remove_calls_for_object(object) Efektory: float add_cam_effector(string <nazwa animacji>, int <identyfikator>, boolean <pętla>, string <callback na zakończenie>) string <nazwa animacji> -- nazwa pliku *.anm, adresowanego z folderu anims int <identyfikator> -- dowolna całkowita liczba, którą można użyć do usunięcia boolean <pętla> -- czy robić to w nieskończoność string <callback na zakończenie> -- nazwa funkcji, która wykonuje się po zakończeniu działania efektu. Funkcja nie przyjmuje argumentów i nie zwraca wartości. Nie jest wywoływana przy wymuszonym zakończeniu efektora funkcją remove_cam_effector. Funkcja zwraca jakąś liczbę, dla każdego pliku animacji własną liczbę. Nieznany cel. float add_cam_effector2(string, number, boolean, string) -- ogólnie jest to samo, co i poprzednia funkcja. Widoczna różnica jest w tym, że poprzednia przesuwała pozycję kamery od obecnej pozycji aktora, a ta od razu przesuwa kamerę aktora do jakieś startowej pozycji. void remove_cam_effector(number <identyfikator>) -- usunąć efektor z wcześniej wpisanym numerem void add_pp_effector(string <nazwa postefektu>, int <dowolny identyfikator>, boolean <pętla>) string <nazwa postefektu> -- nazwa pliku *.ppe, adresowanego z folderu anims int <dowolny identyfikator> -- dla późniejszego usunięcia boolean <pętla> -- czy robić to w nieskończoność void set_pp_effector_factor(int <identyfikator>, float <intensywność>) int <identyfikator> -- liczba wcześniej zadana przy ustawieniu efektu float <intensywność> -- (0, 1) -- intensywność efektu void set_pp_effector_factor(int <identyfikator>, float <intensywność>, number <szybkość zmiany>) int <identyfikator> -- jw. w poprzednim punkcie float <intensywność> -- jw. w poprzednim punkcie number <szybkość zmiany> -- nie jest do końca jasne, ale jest to coś w postaci szybkości przejścia od obecnego stanu do zadanego. Na jakiej podstawie obliczany jest czas przejścia - nie jest to do końca wiadome void remove_pp_effector(int <identyfikator>) -- usunąć efekt Następujące dwie funkcje praktycznie nie są wykorzystywane. Zaangażowane nieznacznie tylko w ZP void add_complex_effector(string <sekcja>, int <identyfikator>) string <sekcja> -- nazwa sekcji w system.ltx, z opisem efektu int <identyfikator> void remove_complex_effector(int <identyfikator>) -- anulowanie efektora Funkcje czasu: int get_time_days() -- dzień miesiąca czasu gry int get_time_hours() -- godzina aktualnego dnia czasu gry int get_time_minutes() -- minuta obecnej godziny czasu gry float get_time_factor() -- zwraca stosunek prędkości upływu czasu gry do prędkości realnego czasu (game_time_speed / real_time_speed) void set_time_factor(number) -- ustawia ten stosunek. Współczynnik czasu generalnie nie wpływa na fizykę świata. To znaczy, prędkość poruszania się obiektów pozostaje naturalna. Kule lecą z tą samą prędkością, co i wcześniej. Ludzie i potwory biegają jak i wcześniej. To, na co dokładnie wpływa czynnik czasu, to zmiana dnia i nocy. Ustawiając go na bardzo duży, można osobiście obserwować zmianę dnia i nocy w przeciągu kilku minut. Pogoda: string get_weather() -- otrzymanie identyfikatora obecnej pogody void set_weather(string , boolean ) -- ustawia pogodę. Identyfikator pogody powinien występować w pliku config\weathers\environment.ltx w sekcji [weathers] inaczej jest wylot. Drugi parametr odpowiada za natychmiastową zmianę pogody. Jeśli true - zmieniamy od razu, jeśli false - to nie wiadomo. void set_weather_fx(string) -- ustawia pogodowy efekt, opisany w pliku weathers\environment.ltx w sekcji [weather_effects]. Są to różnego rodzaju błyskawice, wiatr z mgłą, zaciemnianie, itp. Także w szczególności zrobiono emisję bool is_wfx_playing() -- czy efekt pogodowy jest teraz odtwarzany float rain_factor() -- stopień deszczu. Zależy od wybranej pogody. Zmienia się najwidoczniej automatycznie HUD i interfejs: function start_stop_menu(CUIDialogWnd*, boolean) -- w ZP usunięto. Te funkcje praktycznie nie są wykorzystywane. Otwarcie okien odbywa się przez obiektu HUD'a function add_dialog_to_render(CUIDialogWnd*) function remove_dialog_to_render(CUIDialogWnd*) CUIWindow* main_input_receiver() -- Zwraca otwarte okno (inwentarza, handlu, PDA, dialogu) Z jej pomocą do standardowych okien można dodać nowe elementy. W ZP jej nie ma! (podziękowania dla Колмогор za dopełnienie) void show_indicators() -- wyświetla wskaźniki i celownik void hide_indicators() -- chowa wskaźniki i celownik void disable_input() -- blokuje mysz i klawiaturę void enable_input() -- odblokowuje mysz i klawiaturę float get_snd_volume() -- poziom dźwięku (0,1) niezwiązany z suwakami w opcjach void set_snd_volume(number) -- ustawić poziom dźwięku (0,1) ESingleGameDifficulty get_game_difficulty() -- poziom trudności gry, z paskami w opcjach nie związany void set_game_difficulty(enum ESingleGameDifficulty) -- ustawić poziom trudności gry. Wyliczenie ESingleGameDifficulty zostało wyeksportowane jako klasa game_difficulty Jego opis: C++ class game_difficulty { const novice = 0; const stalker = 1; const veteran = 2; const master = 3; } to znaczy wywołujemy funkcję w taki sposób: level.set_game_difficulty(game_difficulty.veteran) Praca z różnymi obiektami na poziomie: game_object* object_by_id(number) -- obiekt klienta wg jego id (lub nil, jeśli obiekt nie jest online lub nie ma go) void spawn_phantom(const vector&) -- tworzy fantoma (potwora) we wskazanym punkcie (jak na radarze). Fantom zaczyna zbliżać się do aktora i gdy dotrze do niego - znika function patrol_path_exists(string) function vertex_in_direction(number, vector, number) vector vertex_position(number) -- pozycja level-vertex wg jego numeru. Na każdym poziomie są swoje vertex'y. Numeracja na różnych poziomach może (i ogólnie mówiąc obowiązkowo będzie) podobna function cover_in_direction(number, const vector&) Zarządzanie mapą: void map_add_object_spot(int , string <rodzaj znacznika>, string <napis>) -- ustawić znacznik int -- identyfikator obiektu string <rodzaj znacznika> -- nazwa rodzaju znacznika, zarejestrowana w pliku config\ui\map_spots.xml i wszystkich, które są w nim zawarte za pomocą słowa include string <napis> -- napis void map_add_object_spot_ser(int , string <rodzaj znacznika>, string <napis>) -- różnica pomiędzy tą a poprzednią funkcją jest taka, że druga stawia znacznik na stałe lub innymi słowy na serwerowy obiekt (dlatego i _ser na końcu). Przy wywołaniu od razu nie zauważycie różnicy, ponieważ obie funkcje stawiają znaczniki zarówno na obiekt na obecnym poziomie, jak i na dowolnym innym. Jednakże po zapisie i wczytaniu znacznika, postawione przez drugą funkcję zostaną. Oczywiście, każda z funkcji jest przydatna w takich przypadkach: stałe znaczki trzeba stawiać na schowki i zadania, a czasowe można użyć dla radarów i innych rzeczy tego typu. void map_change_spot_hint(int , string <rodzaj znacznika>, string <napis>) -- zmiana napisu na znaczniku bool map_has_object_spot(int , string <rodzaj znacznika>) -- sprawdzić dostępność znacznika void map_remove_object_spot(int , string <rodzaj znacznika>) -- usunąć znacznik Dźwięk: function iterate_sounds(string, number, function) function iterate_sounds(string, number, object, function) function prefetch_sound(string) ŹRÓDŁO: https://ap-pro.ru/forums/topic/1201-spravochnik-po-funkciyam-i-klassam/ 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.