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/
panzyuza 53 Опубликовано 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 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627197
Nazgool 250 Опубликовано 14 Сентября 2011 Поделиться Опубликовано 14 Сентября 2011 Artos Да не стал я так уж лезть в оптимизации. Хотел и Actor-a вынести, да плюнул. За это стоит только зацепиться и ... :-) Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627199
=VENOM= 51 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 Artos, насчёт модератора - это ты прав, пускай он даст оценку действиям - и моим, и твоим, в том числе. А раз ты куратор темы, то ответь мне на вопрос (то есть, помоги разобраться). Цитирую: Слова о связи этого конкретного респавнера 'esc2_respawn_bandits_fabrika' упомянута именно из-за его закомментированной логики связанной с конкретным гулагом. И его близким расположением - ведь работа выбирается от ближайшей ...Прекрасно понятно (другим, а не тебе) что разработчиками этот респавнер предназначался именно для этого гулага. Хотя по сути, он также может служить и для других гулагов. Говоря о том, что "разработчиками этот респавнер предназначался именно для этого гулага", ты связывался с разработчиками по этому вопросу, или это твои домыслы? Поясняю: это критически важно для моей модификации игры, серьёзно. Не спрашивай "зачем" - просто ответь. Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627208
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 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627210
abramcumner 1 229 Опубликовано 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 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627224
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 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627227
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 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627230
*Shoker* 322 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 Artos Разве в рестрикторах нет логики, которая обрабатывается не зависимо от того, находится ли в нём ГГ или нет? Кажется sr_idle или как то так называлась. Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627335
Artos 99 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 *Shoker* И к чему твой вопрос-возражение? Если задаешь вопрос, то потрудись чтобы была понятно его связь с чем-либо конкретно. Раз начали в тонкости и конкретику впадать, то следует конкретизировать слова, дабы не возникло недопониманий и не провоцировать как с респавнерами флуд ' прав-не прав'. Под рестриктором, как правило, подразумевают объект класса 'SPC_RS_S' (cекцией 'space_restrictor'). Именно про них ведем речь. Если иначе - уточняй. А то и костер (clsid.script_restr) кто-то сейчас к спейс-рестрктору приравняет ... Изначально спейс-рестриктор не имеет своей прописанной логики и требуется в его кастомдату прописать то, что потребно разработчику/модмейкеру. Общие схемы, которые могут быть использованы для рестрикторов прописаны в 'modules.script'. Внесещь в конфиг рестриктора нужные секции и впишешь в активную логику - будет и требуемая логика. Ну а по последнему твоему вопросу - и что же будет обрабатывать некоей своей 'встроенной логикой' рестриктор? Если ты о вопросе 'antreg'-а, то ... какой вообще смысл от дефолтного рестриктора? Ему требовалось по событию 'актор на Кордоне и есть инфопоршень' - произвести было спавн. В этом контексте твой вопрос-возражение не могу понять. Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627438
*Shoker* 322 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 (изменено) > http://www.amk-team.ru/forum/index.php?s=&...st&p=627193 < Такой спейс-рестриктор должен тогда быть размером со всю локацию (весь затон в его радиусе), ... Ну и ...? Можно конечно и правой пяткой почесать правое ухо, но зачем? ;-) В третий раз повторю: В условии вопроса говорилось, что "если актор на Кордоне" ... Ты предложил проверку "текущая локация Кордон?" заменить на некий рестриктор, который по некоей дефолтной логике что-то должен сделать? В теории конечно можно, (пятка дотянется до уха). Ты считаешь что работа любой основной схемы логики, которая выполняед достаточно большое кол-во перекрестных перепроверок и пр. будет эквивалентной заменой паре простейших проверок (см. код е #2761)? Мне непонятно дальнейшее выяснение темы рестриктора в контексте заданного вопроса, т.к. очевидно, что это проигрышный вариант. --/ Artos Изменено 15 Сентября 2011 пользователем Artos Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627497
_Призрак_ 11 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 А зачем размером со всю локацию? У меня инфопоршни выдавались по on_info даже когда спейс_рестриктор был за пределами а-лайфа Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627506
*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* Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627507
panzyuza 53 Опубликовано 15 Сентября 2011 Поделиться Опубликовано 15 Сентября 2011 Действительно, гораздо проще реализовать через рестрикторы(что я и сделал).И схема sr_idle действительно многофункциональна и для данных условий просто необходима.Даже часть скриптовых функций на квесты можно реализовать через рестрикторы.Не такая уж у них и сложная логика.Главное не ошибиться в передаче параметров и логических цепочках.Поизучав все возможные виды логики у рестрикторов и функции скриптов xr_conditions и xr_effects, выяснил, что в данной связке есть огромные возможности.И гораздо проще в обращении, если правильно понять. Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627512
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 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627514
Nazgool 250 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 (изменено) *Shoker*, panzyuza То, что вы спорите и "бьетесь", отстаивая своё мнение хорошо конечно. Сам любитель "подраться". Но в этом бою вы находитесь заведомо в проигрышной ситуации. Ваш оппонент обладает багажом разнообразных приемов и опытом их применения. Вам есть чем ответить? Может какой-нибудь туз в рукаве завалялся? Неизвестный приём? Не думаю. Так что нужно выбрать, либо готовиться к бою изучая приемы соперника, находить свои, либо броситься в драку и получить по всей программе. Изменено 16 Сентября 2011 пользователем Gun12 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627540
Artos 99 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 (изменено) Gun12 Тут не о 'драке' иль споре пока говорить стОит. И они и ты и я, ИМХО, из одной 'породы' - упертые искатели-познаватели. Готовы сами искать и ковырять, порой что-то находим, как нам кажется стОящее, и не готовы сразу отбросить и довериться сторонним словам и идти иным путем. Тут можно провести аналогию как в школе: Вначале познается арифметика. Слагать/вычитать научились и применяем 1+1 = 2 и т.п. Но когда уже хочется 2+2+2+2+2 - то ... Познаем умножение и рады, что нашелся более 'простой' способ работы с бОльшим числом чисел. Но время идет и уже маловато арифметики - начинаем познавать алгебру и рады, что уравнениями можно еще более просто и быстро решать задачки. Идет время ... и порой уже более серьезные задачки возникают - начинаем познавать и тригонометрия и интегралы и пр ... В общем всему свое время и на каждом этапе каждому кажется, что у него есть приемы и знания, которые ему позоляют решить текущие задачи. Если старшекласник начнет спорить, с второклашкой, что его способ решать задачку лучше чем у второклашки - взаимопонимания они все одно не найдут, пока второклашка не столкнется с более сложной задачкой. Все приходит со временем, и необходимость изучать еще неведомое и пересматривать свои взгляды 'что такое хорошо и что такое плохо'. ;-) Пока своих шишек не набьют - врядли готовы верить на слово иль брать готовое но неведомое, требующее новых знаний. Есть еще один момент. *Shoker* поопытнее чем panzyuza в скриптах, конфигах, логике и второму проще узнать, понять и принять его относительно простые приемы и методы, но(!) ... Первый в основном занимается мелкими модификациями (откуда и пренебрежение ресурсами и оптимизациями), а вот второй (как понимаю), замахнулся на мод с немалым кол-вом локаций и, врядли пока представляет, что тут иной подход нужен. Совочком удобно копать в песочнице, а для рыться траншеи и лопаты маловато, неплох бы экскаватор. Но ... пока и лопата великовата и до руля экскаватора не достать. Вот и применяют уже знакомый и удобный совочек, благо не руками ... Подрастут ...;-) Никого ни чем не хотел задеть иль обидеть. Просто мысли в слух ... [x] Изменено 16 Сентября 2011 пользователем Artos Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627549
speczadanie 0 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 (изменено) Подскажите, какие скрипты работают при образовании лога в случае вылета? Просто где-то чего-то напорол, теперь если что-то вылетает, то лога просто нет! Огорчу. При своих правках ты допустил где-то ошибку, которая приводит к т.н. безлоговым вылетам (пустой лог-файл). За вывод лог-файла (запись в него) отвечает движек, а не скрипты. Причин возникновения ошибок, приводящих к подобным 'безлоговым' вылетам достаточно много и самых разных. Определить причину можно только анализом кодов и исправлением ошибки. Откатись назад в своих правках. --/ Artos Изменено 16 Сентября 2011 пользователем Artos Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627560
Miller 10 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 (изменено) Ребят,подскажите,как можно в случае получения квеста получать инфу на экран,на манер Фоллаута 3? Желательно пример скрипта Давай начнем с того, что этот вопрос немножко не в тему... Теперь по существу: Выдать на экран сообщение о получении/завершении квеста можно воспользовавшись методами, которыми пользовались сами ПЫС, а именно: При создании квеста (game_task) нужно не забыть про тег <text></text>. Подробнее об этом ты можешь прочитать здесь: Создание квестов (базовый уровень) ColT_iT Изменено 16 Сентября 2011 пользователем ColR_iT Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627637
RayTwitty 567 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 Всем привет, есть пару вопросов. 1) Имеется ли способ отлова открытой вкладке в ПДА? Если нет, то какими-нибудь обходными путями это можно выяснить? 2) Имеется скриптовое окно-меню. В нем есть статик, допустим 200х200. В этом статике есть текст, довольно большой. Есть ли возможность сделать, чтобы если текст не влазил в окно статика, появлялся скролл и можно было прокручивать текст? В конфигах есть параметр complex_mode, но он отвечает только за перенос текста на новые строчки, если строка не влазит в размеры статика... Заранее спасибо. Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627715
Malandrinus 615 Опубликовано 16 Сентября 2011 Поделиться Опубликовано 16 Сентября 2011 Shadows, 1) Имеется ли способ отлова открытой вкладке в ПДА? Если нет, то какими-нибудь обходными путями это можно выяснить? через модификации движка. Колмогор ещё делал выдачу инфопорции по переходу на конкретную закладку. 2) Имеется скриптовое окно-меню. В нем есть статик, допустим 200х200. В этом статике есть текст, довольно большой. Есть ли возможность сделать, чтобы если текст не влазил в окно статика, появлялся скролл и можно было прокручивать текст? В конфигах есть параметр complex_mode, но он отвечает только за перенос текста на новые строчки, если строка не влазит в размеры статика... У статика прокрутки нет, на то он и статик. complex_mode кстати не отвечает за перенос, а только за то, чтобы работали вручную расставленные переносы. Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/136/#findComment-627732
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти