panzyuza 41 Опубликовано 14 Сентября 2011 Поделиться Опубликовано 14 Сентября 2011 (изменено) Спасибо за советы.Будем иметь в виду.Но я полагаю, что проще данную функцию спавна вынести в логику самого рестриктора и добавить функции в xr_effects.Примерно так: on_actor_inside = nil %=spawn_dolg_bandit_scene% --Сцена долг против бандитов на Затоне function spawn_dolg_bandit_scene(actor, npc) alife():create("dolg_resp",vector():set(429.889343261719,36.2633438110352,-23.8600177764893),1670996,3693) alife():create("dolg_resp",vector():set(429.889343261719,36.2633438110352,-23.8600177764893),1670996,3693) alife():create("bar_dolg_respawn_2",vector():set(429.889343261719,36.2633438110352,-23.8600177764893),1670996,3693) alife():create("bar_dolg_respawn_3",vector():set(421.454193115234,36.2633438110352,-6.27680397033691),1670996,3693) alife():create("bar_dolg_respawn_3",vector():set(421.454193115234,36.2633438110352,-6.27680397033691),1670996,3693) alife():create("bandit_resp_regular",vector():set(424.308135986328,36.263313293457,-0.790691018104553),1660741,3691) alife():create("bandit_resp_regular",vector():set(424.308135986328,36.263313293457,-0.790691018104553),1660741,3691) alife():create("bandit_resp_veteran",vector():set(424.308135986328,36.263313293457,-0.790691018104553),1660741,3691) alife():create("bandit_resp_master",vector():set(452.111480712891,36.7123184204102,-5.0364670753479),1706851,3691) alife():create("bandit_resp_master",vector():set(452.111480712891,36.7123184204102,-5.0364670753479),1706851,3691) end Та-а-ак, понеслось ... Начали с локации - всплывает некий рестриктор. Что дальше всплывет? Должно быть понятно, что на вопросы "а будет ли загружать что-то? и как лучше?" и подобные - каждая мелочь важна! И что ты ждешь в ответ на это пост, даже не задав вопроса? Критику и очередные готовые коды? --/ Artos Изменено 14 Сентября 2011 пользователем Artos AVS_LOCATION_MOD Ссылка на комментарий
Nazgool 250 Опубликовано 14 Сентября 2011 Поделиться Опубликовано 14 Сентября 2011 Artos Да не стал я так уж лезть в оптимизации. Хотел и Actor-a вынести, да плюнул. За это стоит только зацепиться и ... :-) Ссылка на комментарий
=VENOM= 50 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 Artos, насчёт модератора - это ты прав, пускай он даст оценку действиям - и моим, и твоим, в том числе. А раз ты куратор темы, то ответь мне на вопрос (то есть, помоги разобраться). Цитирую: Слова о связи этого конкретного респавнера 'esc2_respawn_bandits_fabrika' упомянута именно из-за его закомментированной логики связанной с конкретным гулагом. И его близким расположением - ведь работа выбирается от ближайшей ...Прекрасно понятно (другим, а не тебе) что разработчиками этот респавнер предназначался именно для этого гулага. Хотя по сути, он также может служить и для других гулагов. Говоря о том, что "разработчиками этот респавнер предназначался именно для этого гулага", ты связывался с разработчиками по этому вопросу, или это твои домыслы? Поясняю: это критически важно для моей модификации игры, серьёзно. Не спрашивай "зачем" - просто ответь. Ссылка на комментарий
Artos 99 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 (изменено) Окончательный (надеюсь) вариант "Экономичная упаковка таблиц в строку и обратно". 1. При упаковке таблиц типа 'список': {v1,v2,v3,v4} в пак-строку для каждого элемента записывается только однобайтный признак, и опускаются сами индексы. Экономия: Общее кол-во байт всех индексов таблицы, каждый разряд которых 1 байт. Т.е. для списка в 100 элементов экономия: 1х9 + 2х90 + 3х1 - 1 = 191 байт. 2. При упаковке целочисленных чисел > 9, число упаковывается не как десятичная строка, а как хекс-строка. Пример: 12345 == 0х3039 => "12345" ~= "3039" и экономится как минимум 1 байт на каждом числе. При сохранении чисел большой разрадности (до 14) - экономия может составлять 3 байта на каждое число. 3. Таблицы должны содержать только элементы типов: строка, число, булево значение, субтаблицы и nil. Элементы типов: юзердата, функция, поток - запрещены для упаковки. 4. Исправлена ошибка AMK-варианта при упаковке таблиц с булевыми значениями в полях. 5. Совместимость со скриптами и сэйвами, использовавшими упаковку/распаковку из amk.script. Обратная совместимость отсутствует. Пример практичеккого применения: В игре в таблицу запоминаются игровые идентификаторы (ID) объектов. Для 198 объектов: Паковка таблицы амк-вариантом: 1925 байт Паковка таблицы 'экономным': 1065 байт --/------------------------------------------------------------------ --/ Упаковка таблицы в строку (стринг) и обратная распаковка --/------------------------------------------------------------------ --/ Внимание! Строки в структуре таблицы не должны содержать символов с кодами 0-31. --[[-------------------------------------------------------- Формат упаковки: table ::= ( listtable | hashtable ) subtable ::= ( listtable | hashtable ) listtable ::= 0x6 valuetype ( value | subtable 0x5 ) hashtable ::= keytype key valuetype ( value | subtable 0x5 ) keytype ::= ( 0x1 | 0x2 | 0x7 ) valuetype ::= ( 0x1 | 0x2 | 0x3 | 0x4 | 0x7 ) --]]-------------------------------------------------------- local tPackChar = { --/ служебная таблица маркеров упаковки d = {1, string.char(1)}, --/(SOH) - 'number' (dec) s = {2, string.char(2)}, --/(STX) - 'string' b = {3, string.char(3)}, --/(ETX) - 'boolean' t = {4, string.char(4)}, --/(EOT) - 'table' e = {5, string.char(5)}, --/(ENQ) - table-end l = {6, string.char(6)}, --/(ACK) - table-list h = {7, string.char(7)} --/(BEL) - number-hex } --/-------------------------------------------------------- --/ функции для совместимости с сэйвами на базе amk.script --/-------------------------------------------------------- --/ упаковка таблицы в строку (стринг) function pack_array_to_string(tTbl,bList) return this.Pack_Tbl(tTbl,bList) --/> String end --/ распаковка 'упакованной' строки (стринга) в таблицу function unpack_array_from_string(sStr) if sStr and sStr ~= '' then --/ amk-format упаковки был тэгирован символом c кодом 1 (0x1) -- if sStr:sub(1,1) == string.char(1) then --/ amk-format? if (sStr:sub(2,2) == tPackChar.d[2] or sStr:sub(2,2) == tPackChar.s[2]) then --/ далее (со 2-го символа) начинается упакованная строка таблицы sStr = sStr:sub(2,-1) --/ отрезаем 1-й символ end end --/< ------------------------------------------------------------ return this.Parse_Str(sStr) or {} --/> Table end return {} --/> Zero-Table end --/-------------------------------------------------------- --/ упаковка таблицы (списка) 'tTbl' в строку 'sStr' --/-------------------------------------------------------- function Pack_Tbl(tTbl,bList) --/< table [,(nil|true|false)] if type(tTbl) ~= 'table' then printf("Pack_Tbl:Not_Table=["..type(tTbl).."]:<Warning!>") return "" --/> zero-string (не таблица!) elseif not next(tTbl) then --/ отсутствует 1-й элемента таблицы? return "" --/> zero-string (таблица пуста) end --/ упаковка ключа (индекса) элемента таблицы local function Pack_Key(key,sType) if sType == 'number' then if key > 9 and key == math.floor(key) then --/ 2-х байтовое или более и целочисленное? return tPackChar.h[2] .. string.format('%X', key) --/> 'hex'-строка else return tPackChar.d[2] .. key --/> 'dec'-строка end elseif sType == 'string' then return tPackChar.s[2] .. key --/> строка end abort("Pack_Tbl:UnSupported_KeyType=" .. tostring(sType) end --/ упаковка значения элемента таблицы local function Pack_Value(value,sType) if sType == 'number' then if value > 9 and value == math.floor(value) then --/ 2-х байтовое или более и целочисленное? return tPackChar.h[2] .. string.format('%X', value) --/> 'hex'-строка else return tPackChar.d[2] .. value --/> 'dec'-строка end elseif sType == 'string' then return tPackChar.s[2] .. value --/> строка elseif sType == 'boolean' then return tPackChar.b[2] .. ((value and "1") or "0") --/> 'bool'-строка ('0'|'1') elseif sType == 'table' then return tPackChar.t[2] .. this.Pack_Tbl(value) .. tPackChar.e[2] --/> рекурсивный вызов end abort("Pack_Tbl:UnSupported_ValueType=" .. tostring(sType) end --/ all pack local tStr,iCntIdx = {},0 --/ проверка: таблица типа 'список'? --/ TODO: проконтролировать на корректность работы с различными типами таблиц if bList == nil then --/ если не задан тип таблицы - определяем 'список' или нет --/ элементов 'списка' > 0|9, 1-й индекс начинается с 1 и за 'списком' отсутствует хеш-элемент iCntIdx = #tTbl --/ длина индексированной части таблицы bList = iCntIdx > 0 and not next(tTbl,iCntIdx) --/ (by Gun12) флаг списка (true|false) end --/< ---------------------------------------- if bList then --/ упаковывается список? table.insert( tStr, tPackChar.l[2] ) --/< маркер 'list' (список) for i=1,iCntIdx do local v = tTbl[i] table.insert( tStr, Pack_Value(v,type(v)) ) end else --/ полная упаковка (ключ и значение) for k,v in pairs(tTbl) do table.insert( tStr, Pack_Key(k,type(k)) ) table.insert( tStr, Pack_Value(v,type(v)) ) end end return table.concat(tStr),bList --/> строка [и флаг 'список'] end --/-------------------------------------------------------- --/ распаковка строки 'sStr' (или части строки от 'at') в таблицу 'tTbl' --/-------------------------------------------------------- function Parse_Str(sStr,at) local tTbl,iLen = {},sStr:len() --/ заготовка таблицы и длина строки if not at then at = 1 end --/ по умолчанию: парсинг с начала строки local key,value,iByte = nil,nil,nil --/ ------------------------------------------- iByte,at = Get_Byte(sStr,at) --/ код at-го символа в строке --/ проверка: упакована таблица типа 'список' (table-list)? local bList = iByte == tPackChar.l[1] --/ флаг: 'начало списка' (table-list) if bList then --/ 'список'? iByte,at = this.Get_Byte(sStr,at)--/ пропускаем маркер списка и переходим к следующему символу end --/ цикл парсинга строки с at-го символа while at < iLen do --/ (суб)строка не закончилась? if iByte == tPackChar.e[1] then --/ проверка: маркер конца субтаблицы? return tTbl,at --/> субстрока субтаблицы закончилась - выход из функции end if not bList then --/ режим 'общей' таблицы (не 'список')? --/ парсинг 'key' if iByte == tPackChar.s[1] then --/ 'string'? key,at = this.Get_Str(sStr,at) elseif iByte == tPackChar.d[1] then --/ 'number' (dec)? key,at = this.Get_Num(sStr,at) elseif iByte == tPackChar.h[1] then --/ 'number-hex'? key,at = this.Get_Num(sStr,at,true) --/< 'true' - флаг распаковка 'hex'-строки else --/ ошибка формата упаковки abort("Parse_Str:(%s):UnSupported_TypeKey=" .. tostring(iByte) end iByte,at = this.Get_Byte(sStr,at) --/ код следующего символа строки end --/ парсинг 'value' if iByte == tPackChar.d[1] then --/ 'number' (dec)? value,at = this.Get_Num(sStr,at) elseif iByte == tPackChar.h[1] then --/ 'number-hex'? value,at = this.Get_Num(sStr,at,true) --/< 'true' - флаг распаковка 'hex'-строки elseif iByte == tPackChar.s[1] then --/ 'string'? value,at = this.Get_Str(sStr,at) elseif iByte == tPackChar.b[1] then --/ 'boolean'? value,at = this.Get_Bool(sStr,at) elseif iByte == tPackChar.t[1] then --/ 'table'? value,at = this.Parse_Str(sStr,at) --/> рекурсивный вызов для 'табличных субстрок' else --/ ошибка формата упаковки abort("Parse_Str:(%s):UnSupported_TypeValue=" .. tostring(iByte) end --/ запоминаем элемент в таблицу if bList then --/ элемент списка? table.insert(tTbl, value) --/ добавляем в таблицу типа 'список' (table-list) else --/ элемент 'общей' таблицы tTbl[key] = value end iByte,at = this.Get_Byte(sStr,at) --/ код следующего символа строки end return tTbl,at --/> end --/ получение кода at-го символа строки и индекса следующего за ним символа function Get_Byte(sStr,at) return string.byte(sStr:sub(at,at)), at+1 --/> end --/ по-символьный парсер строки 'sStr' от at до 1-го 'управляющего' символа function Get_Str(sStr,at) --/< стринг(строка) и начальный индекс в нем local iLen = sStr:len() --/ индекс конца стринга(строки) for i=at,iLen do if string.byte(sStr:sub(i,i)) < 32 then --/ 'управляющий' символ? if i == at then --/ 1-м символом идет управляющий? (пустая строка) return "", i --/> zero-string,iNext end --/ начальная часть (суб)строки и индекс 1-го упр.символа return sStr:sub(at,i-1), i --/> sSubStr,iNext end end --/ вся (суб)строка до конца и индекс 'после конца' return sStr:sub(at,iLen), iLen+1 --/> sSubStr,iNext end --/ перевод части (от 'at') строки 'sStr' в число (десятичное) function Get_Num(sStr,at,bHex) local sSubStr,iNext = this.Get_Str(sStr,at) local iNum = nil if bHex then --/ распаковка хекс-строки? iNum = tonumber(sSubStr,16) --/ перевод 'hex'-строки в десятичное число else iNum = tonumber(sSubStr) --/ перевод 'dec'-строки в десятичное число end if iNum then --/ есть число? return iNum, iNext --/> elseif sSubStr == "" then --/ пустая субстрока? printf("Get_Num:SubStr=" .. tostring(sSubStr) return 0, iNext --/> #?# пока не будем прерывать else --/ ошибка формата упаковки abort("Get_Num:SubStr=" .. tostring(sSubStr) end end --/ перевод части (от 'at') строки 'sStr' в булево значение (true|false) function Get_Bool(sStr,at) local sSubStr,iNext = this.Get_Str(sStr,at) return (sSubStr == "1" or string.lower(sSubStr:match('^%s*(%S*)') or '') == 'true'), iNext --/> end --/------------------------------------------------------------------ Критика, вопросы и пожелания приветствуются. P.S. Внес неск. косметических правок. P.P.S. Правка: Убрана излишняя проверка на 1-й индекс списков. 15.09.2011 10:30 МСК ============================================================ =VENOM= Кура́тор (от лат. curator) — тот, кто наблюдает за ходом определённой работы или иным процессом.Исходя из этого общего определения, куратор не обязан по своей должности отвечать или обучать. Отвечать или нет - это его личное право, как одного из форумчан. Отвечая не на твой вопрос, но связанный по теме и уже задававшийся в ЛС: То, что раздел имеет названием "Школа модинга" (ИМХО не очень удачное), не означает что тут как в общеобразовательной школе имеются штатные учителя. Эта школа САМОобразовательная! Сами форумчане создали ее, сами же обучают друг другу, делясь знаниями. Никто тут ничем не обязан ни кому, кроме соблюдения правил портала и общепринятых. По существу вопроса: Нет смысла мусорить словами о связях с разработчиками ... Ответ каждому ясен - нет, конечно. Можено назвать домыслами, можно и логическим выводом. 1. Само название, данное разработчиками респавнеру 'esc2_respawn_bandits_fabrika' - говорит о прямой связи с АТП-шным гулагом 'esc_fabrika_bandit'. Иных ассоциаций врядли можно придумать. Или у тебя и тут есть возражения? 2. В all.spawn'е имеется закомментированная строка в секции [respawn] этого респавнера: ';conditions = {+esc_kill_bandits_quest_kill} 80, 0' - которая также (будучи активной), связывала бы разрешение события спавна этим респавнером (отключала бы запрет) с выдачей инфопоршня рестриктором 'esc_fabrika_bandit_space_restrictor', который также имеет и соответствующее название и расположен по коорданатам АТП-шного гулага esc_fabrika_bandit'. 3. По координатам респавнера, по которым разработчики его прописали, можно видеть, что место спавна бандитов - довольно закрытый уголок Кордона у заваленного прохода на ТД, т.е. возле АТП. Учитывая, что при выборе работы в гулагах учитывается и расстояние (выбирается работа ближайшего гулага), ясно, что разработчиками задумано, что бандиты заспавненые этим рестриктором должны в первую очередь попадать в АТП-шный гулаг 'esc_fabrika_bandit' (если там конечно были бы свободные работы). Если эти доводы не являются достаточно логичными и очевидными для слов о 'связи респавнера и гулага' - то ... справку от разработчиков я конечно не предоставлю, а дальше убеждать/доказывать - не намерен. Сама игра это доказывает: После выноса бандитов с АТП и пробежки за квестовой курткой для Шустрого, порой можно встретить в том районе заспавнившуюся именно этим респавнером. кучку бандитов, бредущих на АТП. Если их не трогать - они и оседают на АТП, зачистив его от разведчиков Толика (если те еще живы). Изменено 16 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
abramcumner 1 159 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 (изменено) 3. По координатам респавнера, по которым разработчики его прописали, можно видеть, что место спавна бандитов - довольно закрытый уголок Кордона у заваленного прохода на ТД, т.е. возле АТП. Учитывая, что при выборе работы в гулагах учитывается и расстояние (выбирается работа ближайшего гулага), ясно, что разработчиками задумано, что бандиты заспавненые этим рестриктором должны в первую очередь попадать в АТП-шный гулаг 'esc_fabrika_bandit' (если там конечно были бы свободные работы). Неверно. В теории может и должны, но на практике такого никогда не будет. Не забывай, что мы не в топике по оригинальной игре и то, что давным давно уже сделано и работает в некоторых модах твое категоричное "неверно" и "никогда" опроверкает именно практикой! Не глаголь "истины" и не окажешся неправым. --/ Artos Когда этот респавнер заработает, гулаг с бандитами уже будет заполнен из других респавнеров. На практике бандиты из респавнера esc2_respawn_bandits_fabrika идут куда угодно, но не на esc_fabrika_bandit. Почему - смотри ниже. Если эти доводы не являются достаточно логичными и очевидными для слов о 'связи респавнера и гулага' - то ... справку от разработчиков я конечно не предоставлю, а дальше убеждать/доказывать - не намерен. Сама игра это доказывает: После выноса бандитов с АТП и пробежки за квестовой курткой для Шустрого, порой можно встретить в том районе заспавнившуюся именно этим респавнером. кучку бандитов, бредущих на АТП. Если их не трогать - они и оседают на АТП, зачистив его от разведчиков Толика (если те еще живы). Игра доказывает обратное - просто посмотри то, о чем говорил =VENOM= и все поймешь. В онлайне респавнеры не работают из-за неуказанного respawn_radius. Поэтому гулаги заполняются респавнерами, находящимися на другой локации. А бандиты идут вовсе и не на АТП - просто гейм-граф такой. Меньше пустопорожних измышлений, больше практики Поаккуратнее в выражениях, даже улыбаясь следует выбирать слова. А попрактиковаться тебе бы не помешало, а не зашориваться только на кодах оригинала. --/ Artos Добавлено через 19 мин.: =VENOM=, если хочешь, чтобы респавнеры работали в соответствии со своими названиями, то прописывай им respawn_radius. Но не уверен что это хорошая идея - может получаться как на свалке у ангара - непрерывный поток НПЦ. Сейчас от момента спавна до прибытия на точку проходит достаточно много времени именно из-за того, что НПЦ далеко идти от респавнера. А если бы все было как говорит Artos, то не успел бы обшмонать бандитов на АТП, как туда уже новые входят Оффтоп. Вообще надо сделать один респавнер на всех на Кордоне - типа в зону приходят. Он штампует сталкеров новичков. На кордоне посадить вербовщиков в долг/свободу/бандиты. Сталкеры подходят к ним, болтают и решают куда вступать. Собираются группами и дуют на базы группировок. А уже оттуда пусть расползаются по всей зоне В зомби пусть попадают зомбированные сталкеры, в монолит полу зомбированные. Типа симуляция. Ну или выставить им по одному респавнеру на базах. Изменено 15 Сентября 2011 пользователем Artos Ссылка на комментарий
Nazgool 250 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 (изменено) Artos Вот тут у тебя лишняя проверка and iFirstIdx == 1 : local iCnt = #tTbl --/ длина индексированной части таблицы local bList = iCnt > 0 and iFirstIdx == 1 and not next(tTbl,iCnt) Почему? Про вычислении длины таблицы local iCnt = #tTbl на самом деле мы прицеливается сразу в 2-х зайцев. Переменная iCnt может иметь (как бы логически) два значения (первый заяц) : 0 - в таблице не найдены поля списка. не 0 - в таблице найдено поле (последовательность полей) списка. Второй заяц : Если 0, то в таблице нет поля с индексом 1 Если не 0, то поле (поля) найдены, значит в этих полях не может не быть поля с индексом 1. В выражении bList = iCnt > 0 производим выстрел по этим зайцам. Спасибо! Ты прав. Просто вначале подстраховался, а потом пересмотрев кучу вариаций с различными структурами таблиц и, удостоверивщись в обязательном наличии 1-го индекса для 'списков', забыл убрать подстраховку. Подправил. Хотя ... в таких функциях, которые дают данные для сэйвов - необременительные перестраховки порой не помешали бы. --/ Artos Изменено 15 Сентября 2011 пользователем Artos Ссылка на комментарий
Artos 99 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 (изменено) abramcumner От имени координатора темы делаю замечание за неадекватные и по сути грубые высказывания. Называть 'пустопорожними измышлениями' без вестких на то оснований и доказательств - это уже переход грани культурного обсуждения/спора, переход на базарную ругань и попытка оскорбить/унизить оппонента. Причем уже не первый раз ... Думаю модератор вечером выскажет свое мнение и примет соответствующее решение. И давайте придерживаться рамок нормальных дискуссий и споров, указывая и на ошибки другого и признавая свои ... По сути поста: Вынужден признать свою оплошность/ошибку, т.к. уже несколько лет прошло как поправив коды оригинальной игры, не знаю забот с респавнерами. Виноват, сам свои же шоры не заметил. Но это не делает слова 'пустопорожними измышлениями', а с большой вероятностью и являются вариантом решения так и не заданного '=VENOM=''ом прямого вопроса. Итак, что имеем в 'se_respawn.script'? Условие, по которому в 'se_respawn:update_online()' отключается респавнер, если ему не задан параметр 'respawn_radius'. Причем этот параметр довольно редко задан и как правило 200-300 метров. Действительно, если не обращать внимания на отсутствие этого параметра - респавн происходил бы в самое неподходяшее время (не успел АТП зачистить - туда уже идут новые) и еще хуже - порой бы НПС спавнились бы из воздуха на глазах у игрока. Начинаем вносить правки, дабы не зависить от причуд респавнеров с других локаций и ждать когда кто-то когда-то дойдет до нужного гулага. Можно конечно в сами секции каждого нужного респавнера занести параметр 'respawn_radius', но ... это довольно много правок в all.spawn'е и при разработке мода довольно не гибкое решение, требующее каждый раз начинать НИ. Правим 'se_respawn.script'. 1. В корне скрипта создает константу, которая не даст спавниться объектам перед глазами игрока: local RESPAWN_RADIUS = utils.cfg_get_number(system_ini(), "alife", "switch_distance", nil, false, 150) --/ радиус респауна - т.е. спавн будем разрещать только тогда, когда игрок находится от респавнера далее чем дистанция алайфа в игре. 2. Вносим правки в онлайн-апдейт: -- Обновление в онлайне function se_respawn:update_online() --'cse_alife_smart_zone.update( self ) --'printf("RESPAWN: [%s] se_respawn update_online", tostring(self:name())) --[[ --/ закомментировали запрет спавна для респавнеров без параметра "respawn_radius" if self.respawn_radius == -1 then sim_statistic.respawn_enabled(self, false) return end --]] local iDist = (db.actor and db.actor:position():distance_to(self.position)) or 0 --/ дистанция до респавнера if (self.respawn_radius or -1) ~= -1 then --/ еcли задан радиус спавна if iDist >= self.respawn_radius then --/ еали задан радиус и актор далеко - разрещаем спавн self:execute() end elseif iDist >= RESPAWN_RADIUS then --/ еали НЕ задан радиус и актор далеко - разрещаем спавн self:execute() else sim_statistic.respawn_enabled(self, false) end end - т.е. отключив запрет для незаданного радиуса спавна мы и обрабатываем рестрикторы с заданным параметром и с незаданным. Для рестрикторов с незаданным радиусом критерием является радиус алайфа. Т.о. у нас заработали все респавнеры на текущей локации и перед носом спавниться НПС не будут. Применительно к гулагу АТП - пока игрок не отойдет после зачистки на достаточную дистанцию - ближайший респавнер не активен. Используя остальные параметры нужных респавнеров - можно при желании регулировать и периоды респавна и пр ... Для принимающих все это за 'пустопорожние измышления' - можно все это наблюдать уже не один год в игре с модом "SIMBION". Так что ... от теории до практики не так уж и далеко и она (практика) зависит от желания и дел, а не от слов, правильных или ошибочных. Изменено 15 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
*Shoker* 322 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 Artos Разве в рестрикторах нет логики, которая обрабатывается не зависимо от того, находится ли в нём ГГ или нет? Кажется sr_idle или как то так называлась. Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Artos 99 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 *Shoker* И к чему твой вопрос-возражение? Если задаешь вопрос, то потрудись чтобы была понятно его связь с чем-либо конкретно. Раз начали в тонкости и конкретику впадать, то следует конкретизировать слова, дабы не возникло недопониманий и не провоцировать как с респавнерами флуд ' прав-не прав'. Под рестриктором, как правило, подразумевают объект класса 'SPC_RS_S' (cекцией 'space_restrictor'). Именно про них ведем речь. Если иначе - уточняй. А то и костер (clsid.script_restr) кто-то сейчас к спейс-рестрктору приравняет ... Изначально спейс-рестриктор не имеет своей прописанной логики и требуется в его кастомдату прописать то, что потребно разработчику/модмейкеру. Общие схемы, которые могут быть использованы для рестрикторов прописаны в 'modules.script'. Внесещь в конфиг рестриктора нужные секции и впишешь в активную логику - будет и требуемая логика. Ну а по последнему твоему вопросу - и что же будет обрабатывать некоей своей 'встроенной логикой' рестриктор? Если ты о вопросе 'antreg'-а, то ... какой вообще смысл от дефолтного рестриктора? Ему требовалось по событию 'актор на Кордоне и есть инфопоршень' - произвести было спавн. В этом контексте твой вопрос-возражение не могу понять. "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
*Shoker* 322 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 (изменено) > http://www.amk-team.ru/forum/index.php?s=&...st&p=627193 < Такой спейс-рестриктор должен тогда быть размером со всю локацию (весь затон в его радиусе), ... Ну и ...? Можно конечно и правой пяткой почесать правое ухо, но зачем? ;-) В третий раз повторю: В условии вопроса говорилось, что "если актор на Кордоне" ... Ты предложил проверку "текущая локация Кордон?" заменить на некий рестриктор, который по некоей дефолтной логике что-то должен сделать? В теории конечно можно, (пятка дотянется до уха). Ты считаешь что работа любой основной схемы логики, которая выполняед достаточно большое кол-во перекрестных перепроверок и пр. будет эквивалентной заменой паре простейших проверок (см. код е #2761)? Мне непонятно дальнейшее выяснение темы рестриктора в контексте заданного вопроса, т.к. очевидно, что это проигрышный вариант. --/ Artos Изменено 15 Сентября 2011 пользователем Artos Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
_Призрак_ 11 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 А зачем размером со всю локацию? У меня инфопоршни выдавались по on_info даже когда спейс_рестриктор был за пределами а-лайфа Freedom Ссылка на комментарий
*Shoker* 322 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 (изменено) Нет, я предлагал как вариант ковыряние в пысовских скриптах заменить на тот способ, которым пользовались сами GSC. Тем паче что там гораздо проще сделать сложные проверки за счёт готовых функций из xr_conditions\effects А от того что такая логика тяжелее на несколько миллисекунд (по сравнению с прямой писаниной в скриптах) процессоры ни у кого не сгорят, а Сталкер не перестанет запускаться. Зато не будет кучи бесполезной скриптовой возни, и логику зачастую легче освоить чем сложные скрипты. И вообще это метод самих разработчиков. *** http://www.amk-team.ru/forum/index.php?s=&...st&p=627335 И заметь, я в своём посте указал на твою ошибку (?), что "спейс-рестриктор должен тогда быть размером со всю локацию" притом что по моим знаниям - это утверждение не верно, т.к у рестрикторов есть логика вида sr_idle. [logic] active = sr_idle [sr_idle] on_info = {+esc_habar_tonnel_spawn} sr_idle@1 %=spawn_object(esc_trader_habar:esc_trader_habar_2_spawn:0)% [sr_idle@1] on_info = {=actor_has_item(esc_trader_habar)} sr_idle@wait %+esc_actor_inside_habar% [sr_idle@wait] ] Вот я и уточняю - здесь моя ли ошибка, что я считаю что таже логика sr_idle у рестриктора работает не зависимо от нахождения ГГ в зоне онного (что позволяет реализовать идею panzyuza), или же твоя, утверждающая что если ГГ не в зоне действия рестриктора, то никакая логика у него выполнятся не будет. А ты мне опять рассказываешь условие вопроса panzyuza, которое к моему вопросу (именно вопросу-уточнению) вообще ни какого отношения не имеет. Изменено 15 Сентября 2011 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
panzyuza 41 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 Действительно, гораздо проще реализовать через рестрикторы(что я и сделал).И схема sr_idle действительно многофункциональна и для данных условий просто необходима.Даже часть скриптовых функций на квесты можно реализовать через рестрикторы.Не такая уж у них и сложная логика.Главное не ошибиться в передаче параметров и логических цепочках.Поизучав все возможные виды логики у рестрикторов и функции скриптов xr_conditions и xr_effects, выяснил, что в данной связке есть огромные возможности.И гораздо проще в обращении, если правильно понять. AVS_LOCATION_MOD Ссылка на комментарий
Artos 99 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 (изменено) *Shoker* Понятно, один вопрос и одна недомолвка переросли в совершенное иное ... Попробуем разобраться, раз уж адресные вопросы. я предлагал как вариант ковыряние в пысовских скриптах заменить на тот способ, которым пользовались сами GSC. Тем паче что там гораздо проще сделать сложные проверки за счёт готовых функций из xr_conditions\effectsКому что проще - это зависит тоько от познаний и навыков. Да и иные аспекты нередко имеют влиятие на проще или нет. а) Если я разрабатываю один свой мод - мне не обязательно ориентироваться на кого-то, кто паралельно правит один и тот же общий скрипт. Выгода использования общей логики и стандартных схем - в том, что ее использование позволяет распаралелить процесс разработки. б) Если делается патч к уже имеющейся игре/моду, то внесениеизменение логики объектам (если они не вынесены в конфиг-файл) - требует игру начинать заново или же еще более сложными скриптовыми методами замещать/изменять логику из all.spawn'а. в) Мне иль любому скриптеру гораздо проще добавить пару требуемых строк в скрипты, чем тратить гораздо больше времени на распаковку-правку-запаковку алл.спавна. Параллельно (см.предложенный вариант кодов) можно улучшать и оптимизировать и имеющиеся коды, ведь вносимые переменные могут использованы и в других местах. г) Уже вроде как пояснил, что даже если и проще что-то сделать, то лучше ли это для игры - далеко не факт. Повторяю, замена пары простых проверок добавленных в скрипты на порядок менее ресурсоемко, чем простенькое использование аналогичного из общей логики (схем). Зато не будет кучи бесполезной скриптовой возни, и логику зачастую легче освоить чем сложные скрипты. И вообще это метод самих разработчиков.Ты видно не прочитал последнюю часть моего ответа. Если правка иль похотелка простенькая - то нет особого смысла заморачиваться. Каждый делает так, как ему удобно. Если таких правок накапливатся побольше - кто-то начинает уже задумываться о будущем ... Если кол-во заплаток переходит критическую черту - начинаются лаги и пр. проблемы. Уже требуется что-то менять/переделывать. И тот, кто лепил заплатки абы как "лишь бв работало" сталкивается с горой кодов, которые требуется переделать ... и плюет нередко на все это хозяйство. Ну а теперь задумаемся, каким идти путем, если стоит задаче не точечной правки, а начало работы с последующими новыми дополнениями и пр. а) Использовать штатные коды и стандартную логику? Можно конечно ... Но далеко ли уедешь. Возможности штатной логики достаточно широки, но и довольно ограничены. Использование в простых случаях (как с упомянутымм вопросом) - приводит к растранжириванию ресурсов игры и "микросекунды" начинают складываться порой и в секунды. Ну а про посложнее, когда невозможно обойтись штатной логикой - все одно придется делать скриптовые правки. б) Уже упоминал о коллбэках и 'лаунчерах'. Первоначально для написания гибкой и достаточно универсальной системы потребуется и время и знания и навыки. Но(!), взляни на уже упомянутый мод Симбиона или лайнчер из АМК 0.4. Они позволяют решать экономии ресурсов гораздо более гибко и эффективно, чем стандартные метооды. Чтобы решить ту же задачку о проверке локации и инфопоршня, для которой ты предложил перебирать кучу элементов в таблицах в апдейте, достаточно именно "пары" строк, табличка и лаунчер (система коллбэков). При старте игры проверяется локация и требуемые инфопоршни и при необходимости регистрируется необходимость проверять получаемые инфопоршни, и при появлении ожидаемого - запустить трубуемый спавн. Т.о. будет одна общая проверка и действия при старте игры и для Затона будет работать только коллбэк на инфопоршни. По получению ожидаемого инфопоршня - событие спавна и все отключится. В итоге никаких постоянных проверок в апдейте актора с переборами таблиц, никаких постоянных проверок какими-либо рестрикторами и их схемами, никаких лишних объектов и пр. И никакого даже копеешного пожирания ресурсов на других локациях. Так что лучше? Тяп-ляп заплатки? Метод разработчиков? Написание своей системы базовых скриптов? Ответ только один: Все это зависит от конкретной задачи, а при достаточно глобальных правках/добавках - тлько комбинация всех доступных методов позволит сделать оптимально. Выбор алгоритма и способа решения - это основа, и не может быть единого "простого" и оптимального решения для всех задач. Ну и на твой вопрос о 'sr_idle: Разве в рестрикторах нет логики, которая обрабатывается не зависимо от того, находится ли в нём ГГ или нет?Странно заданый вопрос ... вырванный из некоего контекста. Ответ: Нет, логики в 'голом' рестрикторе никакой. Заспавни и сам посмотри. 'Голым' рестриктором (его типом) если только что-то разрешать/запрещить для вхождения в него. Если пропишешь логику типа 'sr_idle' - эта логика будет работать на зависимо от нахождения ГГ в его зоне. И даже более - сама способна проверять этот факт (on_actor_inside). Добавлено через 9 мин.: panzyuza: Действительно, гораздо проще реализовать через рестрикторы Не стану переубеждать, но укажу минусы. - кол-во объектов в игре ограничено числом 65535. Каждый рестриктор - это объект с его ID. - каждый рестриктор (тем более с логикой) биндится, а значит начинает потреблять "копеешные" ресурсы. Несложно прикинуть, во что обойдется "простота", если каждое подходящее событие реализовывать на рестрикторах ... Простота и оптимальность - не синонимы! Изменено 16 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Nazgool 250 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 (изменено) *Shoker*, panzyuza То, что вы спорите и "бьетесь", отстаивая своё мнение хорошо конечно. Сам любитель "подраться". Но в этом бою вы находитесь заведомо в проигрышной ситуации. Ваш оппонент обладает багажом разнообразных приемов и опытом их применения. Вам есть чем ответить? Может какой-нибудь туз в рукаве завалялся? Неизвестный приём? Не думаю. Так что нужно выбрать, либо готовиться к бою изучая приемы соперника, находить свои, либо броситься в драку и получить по всей программе. Изменено 16 Сентября 2011 пользователем Gun12 Ссылка на комментарий
Artos 99 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 (изменено) Gun12 Тут не о 'драке' иль споре пока говорить стОит. И они и ты и я, ИМХО, из одной 'породы' - упертые искатели-познаватели. Готовы сами искать и ковырять, порой что-то находим, как нам кажется стОящее, и не готовы сразу отбросить и довериться сторонним словам и идти иным путем. Тут можно провести аналогию как в школе: Вначале познается арифметика. Слагать/вычитать научились и применяем 1+1 = 2 и т.п. Но когда уже хочется 2+2+2+2+2 - то ... Познаем умножение и рады, что нашелся более 'простой' способ работы с бОльшим числом чисел. Но время идет и уже маловато арифметики - начинаем познавать алгебру и рады, что уравнениями можно еще более просто и быстро решать задачки. Идет время ... и порой уже более серьезные задачки возникают - начинаем познавать и тригонометрия и интегралы и пр ... В общем всему свое время и на каждом этапе каждому кажется, что у него есть приемы и знания, которые ему позоляют решить текущие задачи. Если старшекласник начнет спорить, с второклашкой, что его способ решать задачку лучше чем у второклашки - взаимопонимания они все одно не найдут, пока второклашка не столкнется с более сложной задачкой. Все приходит со временем, и необходимость изучать еще неведомое и пересматривать свои взгляды 'что такое хорошо и что такое плохо'. ;-) Пока своих шишек не набьют - врядли готовы верить на слово иль брать готовое но неведомое, требующее новых знаний. Есть еще один момент. *Shoker* поопытнее чем panzyuza в скриптах, конфигах, логике и второму проще узнать, понять и принять его относительно простые приемы и методы, но(!) ... Первый в основном занимается мелкими модификациями (откуда и пренебрежение ресурсами и оптимизациями), а вот второй (как понимаю), замахнулся на мод с немалым кол-вом локаций и, врядли пока представляет, что тут иной подход нужен. Совочком удобно копать в песочнице, а для рыться траншеи и лопаты маловато, неплох бы экскаватор. Но ... пока и лопата великовата и до руля экскаватора не достать. Вот и применяют уже знакомый и удобный совочек, благо не руками ... Подрастут ...;-) Никого ни чем не хотел задеть иль обидеть. Просто мысли в слух ... [x] Изменено 16 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
speczadanie 0 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 (изменено) Подскажите, какие скрипты работают при образовании лога в случае вылета? Просто где-то чего-то напорол, теперь если что-то вылетает, то лога просто нет! Огорчу. При своих правках ты допустил где-то ошибку, которая приводит к т.н. безлоговым вылетам (пустой лог-файл). За вывод лог-файла (запись в него) отвечает движек, а не скрипты. Причин возникновения ошибок, приводящих к подобным 'безлоговым' вылетам достаточно много и самых разных. Определить причину можно только анализом кодов и исправлением ошибки. Откатись назад в своих правках. --/ Artos Изменено 16 Сентября 2011 пользователем Artos Ссылка на комментарий
Miller 10 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 (изменено) Ребят,подскажите,как можно в случае получения квеста получать инфу на экран,на манер Фоллаута 3? Желательно пример скрипта Давай начнем с того, что этот вопрос немножко не в тему... Теперь по существу: Выдать на экран сообщение о получении/завершении квеста можно воспользовавшись методами, которыми пользовались сами ПЫС, а именно: При создании квеста (game_task) нужно не забыть про тег <text></text>. Подробнее об этом ты можешь прочитать здесь: Создание квестов (базовый уровень) ColT_iT Изменено 16 Сентября 2011 пользователем ColR_iT Ссылка на комментарий
RayTwitty 508 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 Всем привет, есть пару вопросов. 1) Имеется ли способ отлова открытой вкладке в ПДА? Если нет, то какими-нибудь обходными путями это можно выяснить? 2) Имеется скриптовое окно-меню. В нем есть статик, допустим 200х200. В этом статике есть текст, довольно большой. Есть ли возможность сделать, чтобы если текст не влазил в окно статика, появлялся скролл и можно было прокручивать текст? В конфигах есть параметр complex_mode, но он отвечает только за перенос текста на новые строчки, если строка не влазит в размеры статика... Заранее спасибо. Ссылка на комментарий
Malandrinus 615 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 Shadows, 1) Имеется ли способ отлова открытой вкладке в ПДА? Если нет, то какими-нибудь обходными путями это можно выяснить? через модификации движка. Колмогор ещё делал выдачу инфопорции по переходу на конкретную закладку. 2) Имеется скриптовое окно-меню. В нем есть статик, допустим 200х200. В этом статике есть текст, довольно большой. Есть ли возможность сделать, чтобы если текст не влазил в окно статика, появлялся скролл и можно было прокручивать текст? В конфигах есть параметр complex_mode, но он отвечает только за перенос текста на новые строчки, если строка не влазит в размеры статика... У статика прокрутки нет, на то он и статик. complex_mode кстати не отвечает за перенос, а только за то, чтобы работали вручную расставленные переносы. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти