*Shoker* 322 Опубликовано 13 Марта 2012 Поделиться Опубликовано 13 Марта 2012 (изменено) Artos Я так понял ему надо изменит нет-пакетом параметры фонарика или какого то другого инвентарного предмета. Сам с этим столкнулся совсем недавно, пришлось для перевода сперва выкидывать предмет на землю, а потом загонять обратно в инвентарь. Изменено 13 Марта 2012 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
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 Ссылка на комментарий
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 Ссылка на комментарий
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 Ссылка на комментарий
Artos 99 Опубликовано 13 Марта 2012 Поделиться Опубликовано 13 Марта 2012 (изменено) Цитата из мануало о том, как задавать вопросы: Описывайте цель, а не отдельный шаг Если вы пытаетесь разобраться, как что-либо сделать (а не сообщаете об ошибке), начинайте с описания цели. И только потом описывайте конкретный шаг на пути к ней, который вы не смогли выполнить. Зачастую люди, которым необходима техническая помощь, имеют на уме высокоуровневую цель и привязываются к одному из возможных, по их мнению, путей ее достижения. Они просят помочь выполнить один шаг, не отдавая себе отчета в том, что выбрали неверный путь. Чтобы разобраться в этом, может потребоваться много усилий. *Shoker*, мною был задан адресный вопрос и суфлерство в данном случае как раз неуместно (и перепрочти цитату). AndreySol, вот желание скриптово вкл/выкл фонарик - еще как то можно назвать целью, а потуги с нет-пакетами и офф/онлайном - это средства. СтОит это все же различать. (отвечу пока с конца) 1. Учитывая, что фонарик актору достается нахаляву (спавнится в инвентарь автоматом), попадает в слот автоматом и не виден в слоте (в оригинале игры) то спрашивается - а какого лешего фонарик светит во лбу 'голого' актора? А зачем его включать/отключать(,), если можно просто взять и удалить, а когда нужно заспавнить! (ну иль переместить куда-нить во вне актора, например в ящик) Т.о. если целью является лишить актора возможности светить изо лба (фонариком) - то совсем необязательно управлять фонариком, а достаточно просто удалять фонарик или добавлять его актору. В отличии от иных типов предметов (оружие, КПК, ...) свойства фонарика типа "исправность" иль иные никак не влияют ни на что. Учитывая п.3 (см.ниже) - это вполне позволяет достичь желаемой цели. 2. Учитывая, что в ТЧ имеется баг с визуалом актора (вид от 3-го лица) и при получении в инвентарь любого костюма/броника визуал приходится "подправлять" снимая его и надевая - как раз самое удобное и проверять - имеется ли у костюма шлем и если да - переспавнивать фонарик. Ну а если нет на голове ничего - то и фонарик можно не спавнить. Ну это так ... мысли о вообще "что делает на голом лбу фонарик". 3. Если "вспомнить", что игра (сингл) возможна только при условии нахождения актора в онлайне, и движек и скрипты контролируют это - то спрашивается, а вообще как это возможно, что основной объект (родитель/владелец) в онлайне, а его часть (предмет из инвентаря) - в оффлайне? Кто-то может мне это объяснить на пальцах? Ну а если предмет "в слоте" - то вообще неясно, что же игрок/модмейкер подразумевает под перевод предмета в оффлайн так, чтобы он не покидал слот ... Вспоминаем, что телепортируя актора куда-то, мы НЕ занимаемся телепортацией его всего барахла, а это делает движек автоматом! Т.о., если уж приспичило по какой-то нужде выводить объект в оффлайн - то без отделения его от родительского объекта это сделать наврядли возможно. Изменено 13 Марта 2012 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
ColR_iT 171 Опубликовано 13 Марта 2012 Поделиться Опубликовано 13 Марта 2012 (изменено) Artos, извиняюсь за 5 копеек, но боюсь, что Вы оба думаете о разных вещах. Осмелюсь предположить, что AndreySol, хочет именно вкл/выкл фонарик и именно скриптами. Я приблизительно догадываюсь для чего это вообще нужно - батарейки для фонаря, так ведь, AndreySol? Если не ошибаюсь, то фонарик принадлежит классу CTorch, если это так, то набор методов для него скудный и метода вкл/выкл я там не наблюдаю... Изменено 13 Марта 2012 пользователем ColR_iT Ссылка на комментарий
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 "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
AndreySol 215 Опубликовано 14 Марта 2012 Поделиться Опубликовано 14 Марта 2012 ColR_iT Осмелюсь предположить, что AndreySol, хочет именно вкл/выкл фонарик и именно скриптами. Я приблизительно догадываюсь для чего это вообще нужно - батарейки для фонаря, так ведь, AndreySol? Именно так. Artos А зачем его включать/отключать(,), если можно просто взять и удалить, а когда нужно заспавнить! (ну иль переместить куда-нить во вне актора, например в ящик) Это бы работало, если-бы разрабы не связали "движково" фонарик с ПНВ. А так как, по игровой логике, ПНВ связан все-таки с наличием соответствующего бронекостюма, то я и хотел сделать раздельное батарейное питание для ПНВ и фонарика. Но видимо придется принять вариант "одна батарея для фонарика и ПНВ". по п.3 - оно то понятно, насчет родительского объекта, но ведь движок все-же изменяет свойства объектов в слотах\инвентаре актера(ГГ) (к примеру - износ оружия в процессе стрельбы) без изъятия (перевода он-офф-он) их из этих самых слотов\инвентаря. И делает он это явно с использованием нет-пакетов, так как это, видимо, единственный способ синхронизации состояния клиентской и серверной частей объекта. Вот я и думал, что возможно менять свойства путем изменения нет-пакетв объектов даже в инвентаре\слотах актера(ГГ). Я только начал изучать работу с нет-пакетами, и модуль для работы с ними от Artos очень помог. А то, что меня попрекают якобы не знанием "элементарных базовых" основ, это все-же не моя вина - уж очень пахабно движок разрабами писан. И с этим (на мой взгляд) очень тяжело поспорить. Ссылка на комментарий
Artos 99 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 AndreySol, не ставь телегу перед лошадью ... 1. Ты опять перемешал понятия и никак не поймешь разницу между клиентским объектом и серверным. Если износ оружия присущь именно клиентскому объекту, имеет для него соответствующие методы и изменяется именно в онлайне (в слотах), а в серверный объект запоминается при создании сэйва - то это и означает что никакими нет-пакетами тут и не пахнет. Нет-пакеты, по сути, возможность изменить свойства объекта И в онлайне через "задний проход", и хотя этот способ вполне действенен, но все же не для всего, не всегда и конечно же нужно его использовать с умом. 2. AndreySol: ... то, что меня попрекают якобы не знанием "элементарных базовых" основ, это все-же не моя вина - уж очень пахабно движок разрабами писан. И с этим (на мой взгляд) очень тяжело поспорить. Мда-а-а, спорить тут бесполезно ... в таких случаях говорят - "это диагноз". Почему то все другие модмейкеры с этой "похабщиной" работают и создают моды, не сваливая на разработчиков свои проблемы ... "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
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 Ссылка на комментарий
_Призрак_ 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 пользователем _Призрак_ Freedom Ссылка на комментарий
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 "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
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 Что-то кончается, что-то начинается... Ссылка на комментарий
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 "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
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 Ссылка на комментарий
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 "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
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ь GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
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 Что-то кончается, что-то начинается... Ссылка на комментарий
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 "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Viнt@rь 50 Опубликовано 15 Марта 2012 Поделиться Опубликовано 15 Марта 2012 (изменено) Artos, а разве хранение всех данных о нпс в еще одной табличке не даст той же нагрузки, что и проверка? К тому же, как я сказал ранее, радиус алайфа ну черезвычайно маленький(сделать больше - будут лаги), а ведь только онлайновые нпс обновляются... К чему я веду, к тому, что нпс в онлайне на локации мало, а убийств/смертей нпс еще меньше, тоесть проверка выполняется вообще мизерное кол-во раз(правда если ГГ не начнет гамселить всех и вся), так зачем же тогда создавать и заполнять еще одну табличку... если можно получить НПС из стораджа и из него уже "вытянуть" инфу... Твою точку зрения я понял и я с ней согласен, но все же... Если бы, все обьекты (хотя бы одной)локации были онлайн, то, то, что ты предлагаешь, надо делать в первую очередь, так как события происходили бы по всей локе постоянно, а не только там, где находится ГГ, и в таком случае проверка действительно выполнялась бы через чур часто... Ну и ... как ранее заметил Vano_Santuri, все же не стОит алгоритм загонять в жесткие рамки. Если у костра сидит с десяток сталкеров - то ближайший к некоей точке вне костра будет как правило только один - что на "реализЬм" новостей плохо сказывается, превращая этого "ближнего" в штатного корреспондента. Лично у меня, в данном случае, это наблюдатель, для новостей типа видел/слышал, потому, такой вариант мне подходит, нет, даже больше, такой вариант для меня идеален Сорри, чет понесло в оффтоп... Изменено 15 Марта 2012 пользователем Viнt@rь GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти