Svoboда 3 Опубликовано 23 Апреля 2009 Поделиться Опубликовано 23 Апреля 2009 Тема для обсуждения скриптов всего и всех в серии игр STALKER. Задавая вопрос (!): 1. Внимательно изучите суть вопроса. Вопрос должен соответствовать выбранной Вами темы. Это поможет сохранить порядок и читабельность темы, а также облегчит поиск и понимание сего; 2. Изучите то, что уже есть в теме (пролистайте "руками", воспользуйтесь поиском на форуме); 3. Изучите информацию которая может вам помочь: Stalkerin. Там есть много хороших статей касательно данной темы.Уроки по модостроению. Есть рабочие примеры готовых скриптов различного назначения. Справочное руководство по языку Lua 5.1https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual/ruСправочник по функциям и классам. Собрано много информации по функциям и классам, не всем, но по основные сведения предоставлены. Логика со вступлением и четырьмя частями: ВступлениеЧасть перваяЧасть втораяЧасть третьяЧасть четвертая. Smart_terrain (в простонароде - гулаг)Интересный способ настроики логики для гулаговСкриптовая часть игровой логики 4. Дабы не превращать обсуждение в "кашу" разной информативной направленности, задавайте несколько вопросов по порядку (в разных постах) после того, как получите ответ на предыдущий вопрос; 5. "Спасибо" и тому подобное - будьте так любезны в ПМ. Если не любите писать в ПМ, в конце вопроса напишите фразу: "Заранее спасибо!" - или что-то в этом духе; 6. ПОЖАЛУЙСТА! Указывайте, для какой игры Вам необходима информация (ТЧ, ЧН, ЗП), если стоит мод - укажите название мода; 7. Если Вы что-то сделали и результат не такой, какой Вами задумывался, то, пожалуйста, приводите коды которые Вы изменяли/писали целиком! Это поможет другим правильно ответить на Ваш вопрос, а также оградит Вас от лишней писанины. 8. Оформляйте сообщение. Пользуйтесь тегами для того, чтобы отделить код от текста. Пишите грамотно - ПОЛЬЗУЙТЕСЬ ЗНАКАМИ ПРЕПИНАНИЯ. 9. И помните: «Правильно заданный вопрос – половина ответа». Какие вопросы следует задавать, а какие нет... Задавайте вопросы, которые касаются непосредственно скриптов и их работы, т.е. Вы что-то делаете, а у Вас что-то не получается, при этом у Вас на руках должен быть хотя бы какой-то код, свидетельствующий о Вашей причастности к вопросу. Вопросы которые будут удалятся, следовательно их задавать не нужно:-- Где находится та или иная функция? Для ответа используем поиск по словам среди файлов оригинальной игры или мода, если объект поиска относится к нему, при помощью программы, которая Вам наиболее симпатизирует;-- Как сделать что-то/то-то? С подобными вопросами, либо в "ковырялки", где Вам вероятнее всего так же не ответят, либо выдвигаем мысли, подкреплённые теорией, практикой (идеальный вариант) и здравым рассудком;-- Вопросы со смыслом: "сделайте", "совместите" и подобными глаголами повелительного наклонения.-- К тому же удалению будут подвергаться вопросы, в которых масштабно не используются теги, для отделения кода и цитат от основного текста, а также не вписан в спойлер код размером превышающие семь строк.Ответ на возможно возникший вопрос: В какую тему можно обратиться по поводу логики и спавна объектов? В тему "ковырялок" соответствующей версии игры, для которой Вы задаёте вопрос. И последнее: очень рекомендовано к прочтению Правила форума 1 2 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/
*Shoker* 322 Опубликовано 13 Марта 2012 Поделиться Опубликовано 13 Марта 2012 (изменено) Artos Я так понял ему надо изменит нет-пакетом параметры фонарика или какого то другого инвентарного предмета. Сам с этим столкнулся совсем недавно, пришлось для перевода сперва выкидывать предмет на землю, а потом загонять обратно в инвентарь. Изменено 13 Марта 2012 пользователем *Shoker* Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682118
olaf1 0 Опубликовано 13 Марта 2012 Поделиться Опубликовано 13 Марта 2012 (изменено) i have make a script witch shall repswan npc local first_spwan = false local respwan_table = {} local timer = 0 local timer_repswan = 0 local spwan = false function spwawn() local levels = {[0] = "marsh", [1] = "l01_escape", [2] = "l02_garbage", [3] = "l03_agroprom", [4] = "l04_darkvalley", [5] = "l05_bar", [6] = "l06_rostok", [7] = "l07_military", [8] = "l08_yantar"} local level_name = level.name() if spwan == false then if timer == 0 then timer = time_global() + math.random(36, 60) end if db.actor:alive() then if time_global() > timer then timer = 0 for indx, lvl in pairs(levels)do if level_name == lvl then ws = indx spwan = true if spwan == true then if ws == 0 then spawn = alife():create("mar_clear_sky_respawn_1", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id()) alife():create("mar_clear_sky_respawn_2", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id()) alife():create("mar_clear_sky_respawn_3", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id()) respwan_table[spawn.id] = true first_spwan = true end end end end end end end if first_spwan == true then if type(respwan_table) == "table" then local obj,count,tbl_cnt = nil,0,#respwan_table for k,v in pairs(respwan_table) do obj = alife():object(k) if obj == nil then k = respwan_npc_name v = nil if timer_repswan == 0 then timer = time_global() + math.random(36, 60) end if db.actor:alive() then if time_global() > timer_repswan then timer_repswan = 0 spawn = alife():create(respwan_npc_name, vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id()) respwan_table[spawn.id] = true end end end end end end end but when i kill a npc the npc donґt respwan but why? can anyoen help me? thank you No errors, except for some discrepancies. It is not clear assignment script. Describe your idea - what do you want to do? ColR_iT Изменено 13 Марта 2012 пользователем ColR_iT Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682176
AndreySol 215 Опубликовано 13 Марта 2012 Поделиться Опубликовано 13 Марта 2012 (изменено) Artos 1. А для чего переводить в оффлайн находящуюся в рюкзаке у актора, например, аптечку иль иной предмет? Как Shoker и предположил, для изменения нет-пакетом параметров фонарика. Очень хочу попробовать скриптово его вкл\выкл. Состояние его получить могу (исп. Ваш модуль) а вот изменить... 2. А что ты ожидаешь увидеть (когда и где, на экране, в логе, иль еще где) в качестве - "вот предмет находится в оффлайне"? Сообщение. Для этого в Вашем модуле временно добавил в local execute_switchings = function(): .......................... else --/ object in 'offline' - phase-2: local msg = "объект в офф-лайн" news_manager.send_tip(db.actor, msg, nil, nil, 30000) .......................... инициирую в игре перевод он-офф-он, сообщение не приходит. Пробовал, для теста, и с обычной аптечкой - то-же не получается. Похоже, Shoker прав насчет того, что надо вывести предмет из инвентаря\слота и тогда он будет доступен для перевода он-офф-он ? Shoker А как у Вас в общих чертах выглядит пришлось для перевода сперва выкидывать предмет на землю, а потом загонять обратно в инвентарь. Как выкинуть из слота\инвентаря мне понятно, а вот как назад забрать ? Изменено 13 Марта 2012 пользователем AndreySol Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682204
olaf1 0 Опубликовано 13 Марта 2012 Поделиться Опубликовано 13 Марта 2012 (изменено) Sorry that i make a new psot but i donґt knwo how i can at it on my i will make a script what respwan npc i have write a script first what all npcґs spwant and then are this npcґs incold in a table local first_spwan = false local respwan_table = {} local timer = 0 local timer_repswan = 0 local spwan = false function spwawn() local levels = {[0] = "marsh", [1] = "l01_escape", [2] = "l02_garbage", [3] = "l03_agroprom", [4] = "l04_darkvalley", [5] = "l05_bar", [6] = "l06_rostok", [7] = "l07_military", [8] = "l08_yantar"} local level_name = level.name() if spwan == false then if timer == 0 then timer = time_global() + math.random(36, 60) end if db.actor:alive() then if time_global() > timer then timer = 0 for indx, lvl in pairs(levels)do if level_name == lvl then ws = indx spwan = true if spwan == true then if ws == 0 then spawn = alife():create("mar_clear_sky_respawn_1", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id()) alife():create("mar_clear_sky_respawn_2", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id()) alife():create("mar_clear_sky_respawn_3", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id()) respwan_table[spawn.id] = true first_spwan = true end end end end end end end if first_spwan == true then if type(respwan_table) == "table" then local obj,count,tbl_cnt = nil,0,#respwan_table for k,v in pairs(respwan_table) do obj = alife():object(k) if obj == nil then k = respwan_npc_name v = nil if timer_repswan == 0 then timer = time_global() + math.random(36, 60) end if db.actor:alive() then if time_global() > timer_repswan then timer_repswan = 0 spawn = alife():create(respwan_npc_name, vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id()) respwan_table[spawn.id] = true end end end end end end end in the next part of the script the table checked wether the npc is dead is the nc dead a timmer start and after the timer the npc will respwan i hope anyone can understand this sorry for my bad englisch but when i kill a npc ,the npc dont respwan but why? can anyoen help me? thank youolaf1, olaf1, olaf1, Изменено 13 Марта 2012 пользователем ColR_iT Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682205
Artos 99 Опубликовано 13 Марта 2012 Поделиться Опубликовано 13 Марта 2012 (изменено) Цитата из мануало о том, как задавать вопросы: Описывайте цель, а не отдельный шаг Если вы пытаетесь разобраться, как что-либо сделать (а не сообщаете об ошибке), начинайте с описания цели. И только потом описывайте конкретный шаг на пути к ней, который вы не смогли выполнить. Зачастую люди, которым необходима техническая помощь, имеют на уме высокоуровневую цель и привязываются к одному из возможных, по их мнению, путей ее достижения. Они просят помочь выполнить один шаг, не отдавая себе отчета в том, что выбрали неверный путь. Чтобы разобраться в этом, может потребоваться много усилий. *Shoker*, мною был задан адресный вопрос и суфлерство в данном случае как раз неуместно (и перепрочти цитату). AndreySol, вот желание скриптово вкл/выкл фонарик - еще как то можно назвать целью, а потуги с нет-пакетами и офф/онлайном - это средства. СтОит это все же различать. (отвечу пока с конца) 1. Учитывая, что фонарик актору достается нахаляву (спавнится в инвентарь автоматом), попадает в слот автоматом и не виден в слоте (в оригинале игры) то спрашивается - а какого лешего фонарик светит во лбу 'голого' актора? А зачем его включать/отключать(,), если можно просто взять и удалить, а когда нужно заспавнить! (ну иль переместить куда-нить во вне актора, например в ящик) Т.о. если целью является лишить актора возможности светить изо лба (фонариком) - то совсем необязательно управлять фонариком, а достаточно просто удалять фонарик или добавлять его актору. В отличии от иных типов предметов (оружие, КПК, ...) свойства фонарика типа "исправность" иль иные никак не влияют ни на что. Учитывая п.3 (см.ниже) - это вполне позволяет достичь желаемой цели. 2. Учитывая, что в ТЧ имеется баг с визуалом актора (вид от 3-го лица) и при получении в инвентарь любого костюма/броника визуал приходится "подправлять" снимая его и надевая - как раз самое удобное и проверять - имеется ли у костюма шлем и если да - переспавнивать фонарик. Ну а если нет на голове ничего - то и фонарик можно не спавнить. Ну это так ... мысли о вообще "что делает на голом лбу фонарик". 3. Если "вспомнить", что игра (сингл) возможна только при условии нахождения актора в онлайне, и движек и скрипты контролируют это - то спрашивается, а вообще как это возможно, что основной объект (родитель/владелец) в онлайне, а его часть (предмет из инвентаря) - в оффлайне? Кто-то может мне это объяснить на пальцах? Ну а если предмет "в слоте" - то вообще неясно, что же игрок/модмейкер подразумевает под перевод предмета в оффлайн так, чтобы он не покидал слот ... Вспоминаем, что телепортируя актора куда-то, мы НЕ занимаемся телепортацией его всего барахла, а это делает движек автоматом! Т.о., если уж приспичило по какой-то нужде выводить объект в оффлайн - то без отделения его от родительского объекта это сделать наврядли возможно. Изменено 13 Марта 2012 пользователем Artos Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682216
ColR_iT 171 Опубликовано 13 Марта 2012 Поделиться Опубликовано 13 Марта 2012 (изменено) Artos, извиняюсь за 5 копеек, но боюсь, что Вы оба думаете о разных вещах. Осмелюсь предположить, что AndreySol, хочет именно вкл/выкл фонарик и именно скриптами. Я приблизительно догадываюсь для чего это вообще нужно - батарейки для фонаря, так ведь, AndreySol? Если не ошибаюсь, то фонарик принадлежит классу CTorch, если это так, то набор методов для него скудный и метода вкл/выкл я там не наблюдаю... Изменено 13 Марта 2012 пользователем ColR_iT Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682222
Artos 99 Опубликовано 13 Марта 2012 Поделиться Опубликовано 13 Марта 2012 (изменено) ColR_iT, я не зря первоначально задал 'глупые' вопросы и привел цитату. Не мне бы нужно адресовать твой пост, а AndreySol ... Я, пока ничего не думаю, точнее предполагаю любой вариант цели попыток AndreySol, но все они именно сводятся к тому, что: а) свойства объекта напрямую зависят от свойств его владельца, если таковой есть. И глупо пытаться перевести в онлайн гранату из рюкзака находящегося в оффлайне непися или наоборот. Даже если методы для объекта имеются доступны, то движек все одно контролирует подобное и или блокирует/игнорирует или разрешает ... б) цель может достигаться различными способами и зашориваться на одном каком-то - неразумно (мягко выражаясь). Повторю, если хочется именно скриптово управлять - читаем п.а). Нельзя же от скриптов требовать невозможного. Если хочется включать/выключать не давя на кнопки (т.е. через скрипты) включать/выключать - то вариант с переспавном именно это и позволяет делать. Игрок все равно не видит своего фонарика в игре и то, что он гаснет иль загорается - это и есть цель, а то, что фонарика нет в слоте не важно и не заметено! Ну если вес иль объем рюкзака важен(!) - то ничего не мешает внести в алгоритмы расчетов нужные поправки. Если же кто-то захотел управлять именно яркостью/фокусом ... - то тут уже не раз писАлось, что это невозможно через свойства фонарика, доступные в игре. Тут или напрямую ковырять память игры внешними приблудами или делать несколько вариантов фонариков с разными конфигами и "хитро" переспавнивать (подменять) их в зависимости от пожелалки. Но это уже совсем иная тема и никак не относится к исходному вопросу о нет-пакетах и попытках перевода офф/онлайн. Ну а попытки не объясняя конечной цела и заранее навешивание себе и другим в вопросе неких шор - почти всегда приводят и к потере времени и затрудняют и понимание сути вопроса и поиск оптимального и/или доступного решения. Добавлено через 8 мин.: P.S. ColR_iT, метод включения и выключения для фонариков имеется, и о чем упомянуто на предыдущей странице (torch_flags.Active = 1). Управляя флагами через нет-пакеты можно включать/выключать фонарики у неписей (о(в)тключая схему sr_light). Но именно к актору это не применимо, т.к. а) для перечтения измененных флагов фонарик требуется или засэйвить и залоадить или перевести офф-олайн (о чем и речь!) и именно это для актора невозможно. И б) игрок всегда может перебить скрипты имея забинденную <L> ... Изменено 13 Марта 2012 пользователем Artos Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682239
AndreySol 215 Опубликовано 14 Марта 2012 Поделиться Опубликовано 14 Марта 2012 ColR_iT Осмелюсь предположить, что AndreySol, хочет именно вкл/выкл фонарик и именно скриптами. Я приблизительно догадываюсь для чего это вообще нужно - батарейки для фонаря, так ведь, AndreySol? Именно так. Artos А зачем его включать/отключать(,), если можно просто взять и удалить, а когда нужно заспавнить! (ну иль переместить куда-нить во вне актора, например в ящик) Это бы работало, если-бы разрабы не связали "движково" фонарик с ПНВ. А так как, по игровой логике, ПНВ связан все-таки с наличием соответствующего бронекостюма, то я и хотел сделать раздельное батарейное питание для ПНВ и фонарика. Но видимо придется принять вариант "одна батарея для фонарика и ПНВ". по п.3 - оно то понятно, насчет родительского объекта, но ведь движок все-же изменяет свойства объектов в слотах\инвентаре актера(ГГ) (к примеру - износ оружия в процессе стрельбы) без изъятия (перевода он-офф-он) их из этих самых слотов\инвентаря. И делает он это явно с использованием нет-пакетов, так как это, видимо, единственный способ синхронизации состояния клиентской и серверной частей объекта. Вот я и думал, что возможно менять свойства путем изменения нет-пакетв объектов даже в инвентаре\слотах актера(ГГ). Я только начал изучать работу с нет-пакетами, и модуль для работы с ними от Artos очень помог. А то, что меня попрекают якобы не знанием "элементарных базовых" основ, это все-же не моя вина - уж очень пахабно движок разрабами писан. И с этим (на мой взгляд) очень тяжело поспорить. Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682518
Artos 99 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 AndreySol, не ставь телегу перед лошадью ... 1. Ты опять перемешал понятия и никак не поймешь разницу между клиентским объектом и серверным. Если износ оружия присущь именно клиентскому объекту, имеет для него соответствующие методы и изменяется именно в онлайне (в слотах), а в серверный объект запоминается при создании сэйва - то это и означает что никакими нет-пакетами тут и не пахнет. Нет-пакеты, по сути, возможность изменить свойства объекта И в онлайне через "задний проход", и хотя этот способ вполне действенен, но все же не для всего, не всегда и конечно же нужно его использовать с умом. 2. AndreySol: ... то, что меня попрекают якобы не знанием "элементарных базовых" основ, это все-же не моя вина - уж очень пахабно движок разрабами писан. И с этим (на мой взгляд) очень тяжело поспорить. Мда-а-а, спорить тут бесполезно ... в таких случаях говорят - "это диагноз". Почему то все другие модмейкеры с этой "похабщиной" работают и создают моды, не сваливая на разработчиков свои проблемы ... Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682589
olaf1 0 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) can anyone help me?? i have write a script wich shll respwan npcґs in any level i hope you can see what for what is and i hope that anyone help me. when you have question to my script the ask me. local respwan_table = {} local timer = nil local levels = {marsh= {x=-61.996055603027,y=0.92057931423187,z=293.67742919922} } local respwan_npc = { mar_clear_sky_respawn_1 = true, mar_clear_sky_respawn_2 = true, mar_clear_sky_respawn_3 = true, } function spwan() if db.actor:alive() == false then return end local level_name = level.name() if timer == nil then timer = level.get_time_hours() + math.random(3, 6) if timer > 23 then timer = timer - 24 end end if time_global() > timer then timer = nil for lvl, pos in pairs(levels) do if level_name == lvl then local pos = vector():set(pos.x, pos.y, pos.z) local lvi = db.actor:level_vertex_id() local gvi = db.actor:game_vertex_id() for npc,spwan in pairs(respwan_npc)do if spwan == true then respwan_table[alife():create("mar_clear_sky_respawn_1", pos, lvi, gvi).id] = true table.insert(respwan_npc,2,false) end end end end end local tbl_count,obj = 1,nil for k,v in pairs(respwan_table) do obj = db.storage[k] and db.storage[k].object if obj and obj:alive() == false and v == true then table.insert(respwan_npc,2,true) end end end but when i start the game i get a crash but in the log are nothing can anyone help me away? thank you. Изменено 15 Марта 2012 пользователем ColR_iT Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682808
_Призрак_ 11 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) olaf1 Sorry for English:) Firstly, you have logical error in your timer. You have used level.get_time_hours() and time_global() which return not the same type of time. If you open the Referenceща Function and classes (you can find it on our forum) you will see, that level.get_time_hours() returns time in hours,which show which hour now in game, but time_global() returns time in milliseconds,which show how many milliseconds have passed since starting the program. So, you must change underlying code: if timer == nil then timer = level.get_time_hours() + math.random(3, 6) if timer > 23 then timer = timer - 24 end end if time_global() > timer then on this code: if timer == nil then timer = level.get_time_hours() + math.random(3, 6) if timer > 23 then timer = timer - 24 end end if level.get_time_hours() = timer then Secondly, what this code must do? It so.... I can't translate what I think, but it's realy strange code: for npc,spwan in pairs(respwan_npc)do if spwan == true then respwan_table[alife():create("mar_clear_sky_respawn_1", pos, lvi, gvi).id] = true table.insert(respwan_npc,2,false) end end Please, explain:) And the last for now, May be I now why you have crash witout log. In for construction you use 'spwan' which already name of function. Change for npc,spwan in pairs(respwan_npc)do if spwan == true then on for npc,myspwan in pairs(respwan_npc)do if myspwan == true then and try again. Replay after check Изменено 15 Марта 2012 пользователем _Призрак_ Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682823
Artos 99 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) olaf1, _Призрак_, давайте придерживаться общепринятых норм и правил. Это русскоязычный форум и сообщения на нем пишутся на русском языке(!). В сложных случаях можно писать и дублированием сообщения на оригинальном языке, но не следует этим злоупотреблять! olaf1, уже не первый раз пишешь в тему с нарушением правил. Ничто не мешает тебе использовать онлайн-переводчики. Потрудись, плз, это делать в дальнейшем. - Считаю, пусть лучше пишет, как пишет: и на английском-то плохо, а с переводчиком будет совсем кошмар и никто ничего не поймет. Cyclone P.S. Именно для "понимания написанного" и применяется вариант с дублированием на общепринятом и родном! Ну а коды olaf1, уже не раз тут появляющиеся - сложно понять и на Lua-шном языке. ;-) --/Artos И, если интересует ответ на свой вопрос, то переведешь самостоятельно текст ниже: 1. Собственно код написан без синтаксических ошибок и не должен приводить к фатальным ошибкам при запуске игры. Но код очень абсурден, что уже показал _Призрак_, и может приводить к переполнению стека при постоянном использовании table.insert(respwan_npc,2,false) при вызовах. 2. Не знаю что за идея у тебя с 'timer', но если ее выкинуть, то вероятно должно получиться что-то в этом роде: local respwan_table = {} local timer = nil local levels = {marsh= {x=-61.996055603027,y=0.92057931423187,z=293.67742919922} } local respwan_npc = { ["mar_clear_sky_respawn_1"] = true, ["mar_clear_sky_respawn_2"] = true, ["mar_clear_sky_respawn_3"] = true, } function spwan() if db.actor:alive() == false then return end --[[ --/ абсурд! (nonsense!) if timer == nil then timer = level.get_time_hours() + math.random(3, 6) if timer > 23 then timer = timer - 24 end end if time_global() > timer then timer = nil --]] local level_name = level and level.name() local coordinates = levels[level_name] if coordinates then local pos = vector():set(coordinates.x, coordinates.y, coordinates.z) local lvi = db.actor:level_vertex_id() local gvi = db.actor:game_vertex_id() for section,flag in pairs(respwan_npc)do if flag == true then --/ если разрешен спавн local se_obj = alife():create(section, pos, lvi, gvi) --/ спавн НПС по координатам respwan_table[se_obj.id] = section --/ запоминаем ID и секцию заспавненного НПС respwan_npc[section] = false --/ ставим метку запрета повторного спавна end end end --end for id,section in pairs(respwan_table) do local obj = db.storage[id] and db.storage[id].object if not obj or obj:alive() == false then --/ если нет НПС или он мертв: respwan_npc[section] = true --/ метка разрешения спавнить respwan_table[id] = nil --/ чистка (clear) end end end Изменено 15 Марта 2012 пользователем Artos Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682845
Vano_Santuri 33 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) Artos, привет. Извини, но возможно опять глупый вопрос. Не подскажешь, возможно ли организовать две таблички - аналоги db.storage , но что бы одна была сталкеров, а другая для мутантов? Есть ли наработки по этому поводу что бы посмотреть? Объясняю для чего мне это нужно. Для поиска сендера в новостях у меня используется перебор вида: function GetStalkers(ThisObj,RadMin,RadMax,who) for k, v in pairs(db.storage) do local obj = level.object_by_id(k) if (obj) and (IsStalker(obj)) and (obj:alive()) and (obj:id() ~= who:id()) then local ComThisObj = ThisObj:character_community() local ComSender = obj:character_community() if CommunityChenalStatus(ComSender,1) then if (ComThisObj ~= ComSender) then --Данным методом ищем сталкера. if ValNpc(obj)~=true then --Отсекаем квестовых нпс local Pos = ThisObj:position() local Dist = Pos:distance_to(obj:position()) if (Dist < RadMax) and (Dist > RadMin) then table.insert(StkLevelTbl, obj) end end end end end end end function GiveStalker(ThisObj,RadMin,RadMax,who) GetStalkers(ThisObj,RadMin,RadMax,who) if next(StkLevelTbl) then local obj = StkLevelTbl[math.random(#StkLevelTbl)] return obj else return nil end end Первая функция делает перебор - и заносит в табличку подходящие варианты по параметрам. Вторая выбирает рандомный( если же в первую внести return obj вместо table.insert(StkLevelTbl, obj) то мы вечно будем получать одного и того же нпс (в зависимости от радиуса , но практически одного и того же), а извлечение в таблицу и рандомный выбор - устраняют это) - Это на случай, если будет вопрос зачем столько таблиц. Но проблема в том, что в момент этого перебора идет нагрузка и игра на 0,1 сек - зависает (рывок такой получается), что есть не гуд. У меня была идея, но опять неподкрепленная мат.частью: При загрузке игры сделать перебор по всем объектам, в табличку их и затем из нее и перебирать. 1. если объект в оффе, то его взять мне не удается (А есть ли такой способ вообще) 2. не учитываются заспавненные в последующем через скрипт. Т.е. эта идея провалилась с потрохами. Теперь воникла идея с клоном db.storage, но : 1. Можно ли такое реализовать. 2. Стоит ли оно такого? Т.е. прекратятся ли рывки - насколько уменьшится нагрузка при переборе? И вопрос на миллион - есть ли другие варианты? Или как можно снять нагрузку при переборе? З.Ы. Мне не нужно готовых вариантов, я готов учиться - только ткните с чего начать? Artos, Спасибо, все ясно. Буду пробовать. Изменено 15 Марта 2012 пользователем Vano_Santuri Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682850
Artos 99 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) Vano_Santuri, отдельные таблички для объектов 'сталкеры' и 'мутанты' давным давно применяются, например, в Zenobian-моде. У себя в моде (ТЧ/ЧН) тоже давным давно использую подобное, причем и для всех серверных объектов организованы таблицы (сталкеры/монстры) и и для онлайновых свои (сталкеры/монстры/аномалии/вертушки/...). Бери и смотри ... Честно говоря, ты по сути с новостями для ЗП изобретаешь велосипед. Может быть не все и не так, но в динамических новостях для ТЧ давным давно многое сделано, над чем ты сейчас бьешься. Почему бы не посмотреть и не взять то, что имеет смысл и оптимальность? 1. Про отдельные таблички уже говорил. Также, в купе с модулем оффлайн-алайф (иль вырезав из него) вполе реально иметь таблички неписей монстров и пр. по локациям, что дает возможность давать новости сканируя только таблицу нужной локации. 2. Рандомность для исключения повторяемости дело конечно хорошее ... но и не оптимальное. И на локации в нужном месте вполе может оказаться всего один-два подходящих сендера (что сведет на нет весь рандом), да и рандом то "повторяем". Вполне можно организовать что-то типа спам-фильтра, т.е. запоминать одного-двух последних сендеров и их "повторять" только при необходимости. 3. Имена для сендеров также нет смысла вычислять каждый раз. Ведь они то никогда не изменяются для одного и того же непися - вот и определив один раз заносить в табличку и потом брать именно из нее. 4. Учитывая, что сталкера/монстры НЕ ракеты и их перемещение все же имеет конечные скорости - вполне можно сканировать таблички и запоминать координаты их расположения и прочие нужные параметры с некоторой дискретностью (не чаще 1 минуты, например, а то и реже), что разгрузит затратные ресурсы на твои скрипты. Т.о., учитывая, что при загрузке игры все интересующие тебя онлайновые объекты (сталкеры/монстры) регистрируются в db.storage, да и серверные объекты не сложно из метода on_register рассовывать по нужным таблицам(локациям) - то собственно 50% (и даже более) нужных данных ты можешь получить сразу при старте. И не следует зашориваться на db.storage, это все же именно таблица онлайновых объектов и "всех в одной куче". Ни что не мешает организовывать свои таблички по нужным тебе параметрам и их использовать. Естественно, эти таблички должны в процессе игры с какой-то периодичностью актуализироваться. Варианты могут быть самые разные. Например, не так давно я давал рабочий вариант для сканирования в отдельном потоке, используя coroutine. Свеже-заспавненные - также регистрируют себя и в игре вообще и в онлайне, если таковое имеет место быть, так что, остается только заставить все это работать на тебя и твои похотелки, вставив в нужные места нужные коды. Изменено 15 Марта 2012 пользователем Artos Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682858
olaf1 0 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 Этот код предназначен для проверки respwan_npc второй позади = истинное, если он верен ему в таблице (respwan_table) NPC gespwant вплоть до уровня , а затем положил обратно в таблице respwan_npc значение ложной for npc,spwan in pairs(respwan_npc)do if spwan == true then respwan_table[alife():create("mar_clear_sky_respawn_1", pos, lvi, gvi).id] = true table.insert(respwan_npc,2,false) end end Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682866
Artos 99 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) olaf1, оператор table.insert действительно кладет куда указываешь, но(!) все остальные имеющиеся позиции сдвигаются! ... и кладет каждый раз только значение (т.е. false) и твоя исходная таблица превращается в это: respwan_npc = { ["mar_clear_sky_respawn_1"] = true, [2] = false, [3] = false, ... [NNN] = false, ["mar_clear_sky_respawn_2"] = true, ["mar_clear_sky_respawn_3"] = true, } Т.о. ты постоянно наращиваешь существующую таблицу новыми полями, не уничтожая прежние. И использовать для неиндексированной таблицы подобное НЕЛЬЗЯ! Ведь в твоей таблице respwan_npc в качестве ключей идут секции для спавна НПС, а не упорядоченные индексы 1,2,3... Советую почитать материалы по работе с неиндексированными таблицами и ограничения на использование как table.insert / table/remove, так и метода ipairs для таблиц, подобных твоей respwan_npc. Выше, тебе как раз дан вариант, который проверяет значение для ключа-секции спавна НПС и, если оно 'true' - разрешается спавн и этот ключ (секция) помечаются значением 'false', что и исключит повторный спавн пока не изменится это значение. Изменено 15 Марта 2012 пользователем Artos Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682867
Viнt@rь 50 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) Vano_Santuri, а зачем вообще такой геморой? Свободно можно отсекать всех нпс и выбирать самого ближнего к трупу, не заполняя таблицу всеми нпс, которые вокруг. О таблице всех нпс на локе, зачем? радиус алайфа ну совсем мизерный... Мой совет, при убийстве нпс, просто искать живых нпс в определенном радиусе. Я давно заметил, что у тебя, сендером, берется первый попавшийся нпс, но ведь можно сделать так, что при каждом пробеге цикла будет искаться нпс, который ближе всех к трупу, ну тоесть: мой пример: function GetSender(sType, oPos, oKiller) local oSender = nil if sType == "murder" then local iMinDist = 30 local iMaxDist = 100 for k,v in pairs(db.storage) do local oTrav = level.object_by_id(k) if oTrav and IsStalker(oTrav) and oTrav:character_community() ~= "actor" and not ExcludedNpcs(oTrav) then if xr_wounded.is_wounded(oTrav) == false and oTrav:alive() then if oKiller then if oTrav:id() ~= oKiller:id() then fGetSender = true end else fGetSender = true end if fGetSender then local DiffDist = oPos:distance_to(oTrav:position()) if DiffDist < iMaxDist and DiffDist > iMinDist then iMaxDist = DiffDist -- я об этом oSender = oTrav end end end end end end return oSender end ЗЫ это так же логичней/реалистичней, в плане нахождения реального сендера, в добавок - намного оптимальней ЗЫЫ сам щас сижу, новости делаю, когда посмотрел, что там у тебя в скриптах, то увидел много чего лишнего, в смысле достаточно много одинакового кода, можно с помощью одной-двух проверок урезать код в несколько раз... Изменено 15 Марта 2012 пользователем Viнt@rь Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682878
Vano_Santuri 33 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) Viнt@rь, когда посмотрел, что там у тебя в скриптах, то увидел много чего лишнего, в смысле достаточно много одинакового кода, можно с помощью одной-двух проверок урезать код в несколько раз... Да было дело давненько, с таблицами первый раз работал. Просто я тогда мало знал о свойствах объектов (родит, дочерные и т.п). В данный момент я практически все отрезал, совсем по другому замутил. Никогда не думал, что сначала делать алгоритм на бумажке куда полезнее, чем сразу печатать код... Но пока это все в разработке и играбельно будет не скоро... Код твой заценил - теперь понятно, таким образом ты сокращаешь расстояние - неплохо. Я просто не думал о таком алгоритме. Сам придумал? Но db.storage -- куча хлама, как сказал Artos. Я все-таки сделаю себе пару табличек, и чтоб они так "размазано" апдейтились - будет чуток быстрее. Плюс можно будет использовать for k=1,#tbl do local t=tbl[k] end Как я почитал - говорят быстрее будет. Нужно будет проверить... Изменено 15 Марта 2012 пользователем Vano_Santuri Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682880
Artos 99 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) Viнt@rь, Vano_Santuri в-первую очередь оптимизация определяется целями и заданными начальными условиями, а никак не "а вот у меня так, а тут так". Viнt@rь, если ваши "новости" ограничиваются только смертями иль не только, но именно на текущей локации, то использование db.storage может быть и оправдано (зачем городить еще чего-то), но говорить об оптимизации НЕ стОит. 1. Даже многократное выпонение простенькой проверки: if oTrav and IsStalker(oTrav) ... все же лучше выполнять не 500 раз, а всего 100 (к примеру). Ведь подобное можно встретить еще в десятке скриптов ... и порою на том же апдейте ... Так зачем каждый раз проверять НЕ нужное??? 2. Кто бы объяснил, ну зачем каждый раз вычислять и группировку и не принадлежность к актору и "не труп" и расстояние и т.п.? И все это делать единомоментно для всех подходящих по условиям неписей ... Вы идете по простейшему и очевидному пути, но можно сколь угодно его мусолить и оптимизировать - при наращивании кодов/алгоритмов в игре и тем более расширяя новости на всю зону - это тупиковый путь. Вспомните, что все(!) неписи имеют свои апдейты! Вспомнили?! Ну а теперь попробуйте сказать, что организовав один раз свою "новостную табличку" и (от)регистрируя в ней каждого НПС иль монстра по net_spawn/net_destroy и обновляя из уже готового для вас апдейта каждого непися в уже созданной табличке информацию и по координатам и по группировке и по "жив иль мертв" и т.п. вы не получите выигрыша? Ведь за вас движек уже распределяет собственно и процесс сканирования/апдейта и за вас актуализирует все нужные данные, не проверяя за раз всех оптом. Остается всего лишь в нужное время по нужным критериям выбрать из готовой таблички подходящий объект. (это конечно только для онлайновых новостей иль подобного сгодится) Ну и ... как ранее заметил Vano_Santuri, все же не стОит алгоритм загонять в жесткие рамки. Если у костра сидит с десяток сталкеров - то ближайший к некоей точке вне костра будет как правило только один - что на "реализЬм" новостей плохо сказывается, превращая этого "ближнего" в штатного корреспондента. Добавлено через 4 мин.: И ... я не говорил что: "db.storage -- куча хлама, но для конкретной задачи типа новостей от сталкеров, в db.storage действительно для данного алгоритма "куча ненужного хлама". Легко самим посмотреть, что при старте чистой ЗП за Затоне в db.storage более 700 объектов из которых неписей на порядок меньше. (приписывая свои слова другому стОит это делать аккуратно) Изменено 15 Марта 2012 пользователем Artos Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682882
Viнt@rь 50 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) Artos, а разве хранение всех данных о нпс в еще одной табличке не даст той же нагрузки, что и проверка? К тому же, как я сказал ранее, радиус алайфа ну черезвычайно маленький(сделать больше - будут лаги), а ведь только онлайновые нпс обновляются... К чему я веду, к тому, что нпс в онлайне на локации мало, а убийств/смертей нпс еще меньше, тоесть проверка выполняется вообще мизерное кол-во раз(правда если ГГ не начнет гамселить всех и вся), так зачем же тогда создавать и заполнять еще одну табличку... если можно получить НПС из стораджа и из него уже "вытянуть" инфу... Твою точку зрения я понял и я с ней согласен, но все же... Если бы, все обьекты (хотя бы одной)локации были онлайн, то, то, что ты предлагаешь, надо делать в первую очередь, так как события происходили бы по всей локе постоянно, а не только там, где находится ГГ, и в таком случае проверка действительно выполнялась бы через чур часто... Ну и ... как ранее заметил Vano_Santuri, все же не стОит алгоритм загонять в жесткие рамки. Если у костра сидит с десяток сталкеров - то ближайший к некоей точке вне костра будет как правило только один - что на "реализЬм" новостей плохо сказывается, превращая этого "ближнего" в штатного корреспондента. Лично у меня, в данном случае, это наблюдатель, для новостей типа видел/слышал, потому, такой вариант мне подходит, нет, даже больше, такой вариант для меня идеален Сорри, чет понесло в оффтоп... Изменено 15 Марта 2012 пользователем Viнt@rь Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/200/#findComment-682885
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти