Viнt@rь 50 Опубликовано 30 Декабря 2012 Поделиться Опубликовано 30 Декабря 2012 (изменено) Привет всем. Вопрос, (прошу сразу - не пинайте, только начинаю осваивать нет пакеты )))), как можно сохранить(на сохранении актора) нет пакет (local packet = net_packet()) и загрузить(прочитать)(на загрузке актора) ?? не прибегая к таким методам, какие используются в хранилищах Malandrius и xStream??? к примеру мне надо сохранить данные таймера -- сохранение local packet = net_packet() local n = #aTimers.aHigh packet:w_u8(n) if next(aTimers.aHigh) then for sName, oTimer in pairs(aTimers.aHigh) do if type(sName) == 'string' then packet:w_bool(true) packet:w_stringZ(sName) else packet:w_bool(false) packet:w_u32(sName) end packet:w_bool(oTimer.bGameType or false) if oTimer.bGameType then utils.w_CTime(packet, oTimer.iTriggerTime) else packet:w_stringZ(oTimer.iTriggerTime) end packet:w_bool(oTimer.bOnce or false) if not oTimer.bOnce then packet:w_stringZ(oTimer.iInterval) end packet:w_stringZ(oTimer.oFunc) packet:w_bool(true) end end -- загрузка local packet = net_packet() local n = packet:r_u8() for i = 1, n do local bIsStrName = packet:r_bool() if bIsStrName then local sName = packet:r_stringZ() else local sName = packet:r_u32() end local oTimer = oTimers(sName) oTimer.bGameType = packet:r_bool() if oTimer.bGameType then oTimer.iTriggerTime = utils.r_CTime() else oTimer.iTriggerTime = packet:r_stringZ() end oTimer.bOnce = packet:r_bool() if oTimer.bOnce then oTimer.iInterval = packet:r_stringZ() end oTimer.oFunc = packet:r_stringZ(oTimer.oFunc) local bHighPrior = packet:r_bool() oTimer:Start(bHighPrior) end ЗЫ я понимаю, что скорее всего, я понаписывал бред, помогите разобраться, плз ЗЫЫ Всех с наступающим) Изменено 30 Декабря 2012 пользователем Viнt@rь GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
Desertir 202 Опубликовано 31 Декабря 2012 Поделиться Опубликовано 31 Декабря 2012 А что значит недоступны? Надо было все таки написать, но думал по коду было понятно. Недоступны в том плане, что этот метод function bug:get_sel_item() local sel_index = self.list:GetSelectedItem() local sel_item = self.list:GetItem(sel_index) return sel_item end возвращал nil. И в методе start, который вызывается при нажатии на элемент, стоит проверка на существование элемента. Так вот в главном меню (независимо от того, только мы запустили сталкер, или нажали Esc во время игрового процесса) в консоле я видел текст из элемента, на который нажимал. Когда же я запускал окно непосредственно в игре (а ля инвентарь), то в консоле зияли надписи "item not exist", что означало, что элемента несуществует. Кстати классы CUIListItemEx и CUIListItem, вообще говоря предназначены для создания скриптового класса на их основе. Чтоб прямо предназначены я не знал, хотя видел это в кодах GSC. Сейчас я это учел, создал свой класс взял класс у GSC, немного подкорректировал его. И... все заработало. Хотя я не знаю, из за чего точно, вот исправленный код class "my_item" (CUIListItemEx)function my_item:__init(text) super()self:SetWndRect(0,0,172,22)self.fn = CUIStatic()self.fn:SetAutoDelete (true)self:AttachChild(self.fn)self.fn:SetWndRect(0,4,172,22)self.fn:SetText(text)self.fn:SetFont(GetFontLetterica18Russian())self.fn:SetTextColor(255,216,186,140)endclass "bug" (CUIScriptWnd)function bug:__init(owner) super()self:Init(0,0,1024,768)self.bg = CUIFrameWindow()self.bg:Init("ui_tablist_textbox",128,128,256,320)self:AttachChild(self.bg)self.list = CUIListWnd()self.list:Init(138,138,172,172)self.list:EnableScrollBar(true)self.list:ShowSelectedItem(true)self:AttachChild(self.list)self:reset_list()self:Register(self.list,"list")self:AddCallback("list",ui_events.LIST_ITEM_CLICKED,self.start,self)if owner thenself.owner = ownerself.owner:GetHolder():start_stop_menu(self,true)self.owner:GetHolder():start_stop_menu(self.owner,true)elselevel.start_stop_menu(self,true)endendfunction bug:start()local sel_item = self:get_sel_item()if not sel_item then pcon("item not exist") return endlocal name = sel_item.fn:GetText()pcon(name)endfunction bug:reset_list(t)t = t or {"Kardon","Svalka","Agroprom","Bar","Yantar","Military","Pripyat","Chernobyl"}self.list:RemoveAll()for _,value in pairs(t) doself.list:AddItem(my_item(value))endendfunction bug:get_sel_item()local sel_index = self.list:GetSelectedItem()local sel_item = self.list:GetItem(sel_index)return sel_itemendfunction bug:OnKeyboard(dik,keyboard_action)CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)if dik == DIK_keys.DIK_ESCAPE thenif self.owner thenself:GetHolder():start_stop_menu(self.owner,true)self:GetHolder():start_stop_menu(self,true)elselevel.start_stop_menu(self,true)endelseif dik == DIK_keys.DIK_END thenself:reset_list({"Mechenyi","Shustryi","Sidorovich","Barman"})endreturn trueend Теперь в игре в консоль выводится именно то, что я и ожидаю - текст из элемента. Возможно заработало из за того, что в классе элемента создается статик, который приаттачивается к элементу (может так и надо делать?), и в итоге элемент остается где то в памяти, возможно еще чтото. Т.о. объекты то ты добавишь в обоих случаях, а вот поля в листинге (по которым и производится выбор) создаются только в 1-ом. Так что у тебя нет доступа потому, что нет собственно соответствия добавленных объектов полям листинга. Эээ, ну что это, я не по полям получаю объект элемента, я лишь так их сохраняю сохранял в объекте. Получаю то я штатными методами (см. начало этого поста) как в первом, так и во втором случае. Так же скажу, в обоих случаях индексы элементов были, т.е. существовали, и вполне реальные: 0, 1, 2 и т.д. Однако в одном случае по индексу мы получали реальный объект, а в другом случае nil. PS: имхо в скриптах с оконными классами очень трудно найти ошибку, т.к. у нас даже вылета не происходит, а в других случаях вылет без лога, лично мне иногда приходится гадать. ТЧ 1.0004. SAP и Trans mod github Ссылка на комментарий
Artos 99 Опубликовано 31 Декабря 2012 Поделиться Опубликовано 31 Декабря 2012 (изменено) Viнt@rь, при осваивании нет-пакетов, советую отбросить все "дурные" привычки. Нет-пакеты требуют полного понимания "что, как и зачем" и не допускают любых вольностей иль гаданий при их использовании. 1. Объект нет-пакета невозможно сохранить в сэвах, это не CGameObject и не его порождение. Нет-пакеты служат для передачи последовательности байтов и не более. Т.о. можно говорить о передаче требуемых тебе значений и сохранении их уже в некоем объекте (на базе CGameObject), который и записывается в сэйвы,ну и соответственно, из загруженного сэйва считывать из гейм-объекта эти данные в нет-пакет и восстанавливать запомненные значения в нужных переменных. 2. Нет никаких специальных "сохранений актора", т.е. событие "сохранение" и "загрузка" - едины для всего в игре (для всех объектов, находящихся в игре). Просто самым первым сохраняется и считывается именно объект актора и именно этот объект присутствует в игре всегда (другие могут и отсутствовать). Т.о. событие "сохраняются/считываются данные объекта актора" - является верным признаком что сохранение/чтение происходит и может быть использовано в алгоритмах/скриптах игры. 3. Твое желание "не прибегая к таким методам, какие используются в хранилищах Malandrius и xStream" в общем-то понятно, но... разочарую тебя - ничто не дается просто так. СОбственно избегаемые тобою "методы" в первую очередь выполнют роль по созданию технологического объекта на базе одного из подклассов CGameObject и этот объект а) не влияет на уже имеющиеся алгоритмы игры (не мешается и не вносит путаницы) и б) дает возможность записать в него, используя нет-пакет соответствующий этому объекту(!), различные сторонние значения. Это позволяет, как минимум, не использовать тот же нет-пакет актора (а вернее сам объект актора), который не резиновый и имеет ограничение по размеру (для ТЧ - не более 8 кБ). Т.о. , твоя пожелалка по неиспользованию "методов" выволнима только одним доступным в оригинале игры способом - размазывать свои данные по уже имеющимся гейм-объектам... и минусы от этого как раз превышают хлопоты от использования "методов". Ну или ... вносить правки в движек, расширяя его, например для обеспечения писать данные напрямую в "свой" файл. Это тоже имеет свои плюсы, но и немало минусов (поэтому многие даже отказываются от него). 5. Ну и не хочется разбирать твой конкретный код, т.к. все одно он вероятно не будет использован, однако, перепроверь его сам на предмет ошибок. Как минимум это: if bIsStrName then local sName = packet:r_stringZ() else local sName = packet:r_u32() end local oTimer = oTimers(sName) - приведет к ошибке или потере данных (про область видимости переменных никогда не следует забывать!) Desertir, я не считаю, что имеющиеся оконные классы нельзя использовать напрямую, а только через их подклассы. Все зависит от задачи и, во многих случаях, плодить суб-классы излишество. В твоем случае, ИМХО, виновата опять таки область видимости переменных. В своем 1-ом варианте и новом - ты используешь только глобальные переменные (для тех же создаваемых итемов), а во 2-ом варианте - создавал локальные для одного из методов основного класса (reset_list) и уже их (точнее линки на них) добавлял... Как в этом случае ведет себя сборщик мусора не берусь сейчас прогнозировать. Изменено 31 Декабря 2012 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
panzyuza 41 Опубликовано 2 Января 2013 Поделиться Опубликовано 2 Января 2013 (изменено) При обращении к имени cast_planner_to_action получил вылет attempt to call global 'cast_planner_to_action' (a nil value). Значит этот планировщик не работает? На ТЧ. Изменено 2 Января 2013 пользователем panzyuza AVS_LOCATION_MOD Ссылка на комментарий
Malandrinus 615 Опубликовано 2 Января 2013 Поделиться Опубликовано 2 Января 2013 panzyuza, просто нет на самом деле такой функции. В lua_help присутствует, а на самом деле такой нет. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Viнt@rь 50 Опубликовано 2 Января 2013 Поделиться Опубликовано 2 Января 2013 Если сохранить число методом packet:w_stringZ(num), то при его чтении, оно будет строкой, верно? и что бы оно снова стало числом, нужно применить функцию tonumber? GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
Artos 99 Опубликовано 3 Января 2013 Поделиться Опубликовано 3 Января 2013 (изменено) Viнt@rь, нет не верно, если говорить не на сокращенном жаргоне. Во-первых, метод w_stringZ предназначен для запоминания именно строкового значения (string), а не "абы всего что дадут". Поэтому для сохранения числа требуется перевести число в строку: packet:w_stringZ( tostring(num) ) Во-вторых, чтобы снова получить значение, его нужно вначале прочитать, в данном случае методом r_stringZ, ну и если запоминалось и/или предполагается число, то прочитав - нужно перевести полученную строку в число, можно и так: num = tonumber( packet:r_stringZ() ) Но я бы советовал использовать все же именно методы, соответствующие типу данных. Понятие "число" очень неоднозначно. Как минимум есть целые и дробные числа и можно переводами в строки нагородить такого, что игра подавится... ;-) Ну а про "экономию" байтов - уж не завожу разговор. Изменено 3 Января 2013 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Viнt@rь 50 Опубликовано 3 Января 2013 Поделиться Опубликовано 3 Января 2013 (изменено) за пояснение спс, по поводу экономии, возможно вопрос глуповат, но как определить ско лько число занимает байт, по количеству знаков?, и как тогда быть, если сохраняемое число имеет больше 8 знаков? Что "Shift" не работает? ColR_iT Изменено 3 Января 2013 пользователем ColR_iT GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
Artos 99 Опубликовано 3 Января 2013 Поделиться Опубликовано 3 Января 2013 (изменено) Действительно, вопрос глуповат. ;-) Числа бывают разные, как минимум, десятичные, двоичные и шестнадцатиричные... и сколько байт будет занимать то или иное представление - зависит от системы исчисдения! Т.о. и кол-во "знаков", а точнее разрядов, зависит от системы исчисления. (Запусти на своем компе калькулятор в режиме программера и сам посмотри сколько разрядов/байт/бит занимает то или иное число в разных представлениях). В игре, числа (данные Lua-типа == 'number') автоматически запоминаются методом w_float - а это целых 4 байта(!), что позволяет записывать аж 4294967295 - т.е. поболее 9 разрядов (даже почти половину от 10-го). Есть еще метод u64 (8 байт) - но в сэйв это не запомнить. Ну а если приспичило хранить численные цепочки подлинее - то конечно можно и переводом в строку обойтись... желательно в шестнадцатиричном виде. Но ведь никто не отнимал возможности разделять и на группы - вспомни: десятки, сотни, тысячи... Ежели ты "отделишь" кол-во миллионов иль триллионов, то и хранить можно их по отдельности, а потом опять "сливать" с остатком. В строке же, каждый(!) разряд - это байт и плюс еще один заключительный (NULL). Вот и считай... Все, что менее 4294967296 будет занимать 4 байта при записи w_float, а строкою w_stringZ - байты по кол-ву разрядов +1. Т.о. уже более 999 - строковая запись будет съедать больше байт, чем численная! Изменено 3 Января 2013 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Это популярное сообщение. proper70 74 Опубликовано 3 Января 2013 Это популярное сообщение. Поделиться Опубликовано 3 Января 2013 (изменено) Вобщем, опять не знаю, куда лучше написать, решил написать сюда) В процессе изготовления ОП-2 неоднократно возникала мысль попробовать сделать так, чтобы неписи не уходили в оффлайн при достижении лимита switch_distance. Например, для снайперского задания. Чтобы неписей валить не со 150 м, а с 300, а то и больше. В описании к СВД ведь написано, что эффективная дальность 700 м, а реально только на 150 пострелять есть возможность... Можно сказать, что совершенно случайно на АС был обнаружен сталкер на вышке на базе Свободы, который в оффлайн никогда не уходил - все время был виден в бинокль, с любого места локи. Это mil_freedom_stalker0004 в alife_l07_military.ltx. Анализ его конфига показал, что у него уникальный набор предикатов: ; cse_alife_human_abstract properties predicate5 = 2,0,2,2,2 predicate4 = 1,0,0,2 Второго такого набора нет ни в чистом ТЧ, ни в НС. Подстановка его конфига другим неписям привела к восхитительному результату: все эти неписи постоянно оставались в онлайне - на любом удалении от гг. И их логика полностью обрабатывалась как нужно. Благодаря этому в ОП-2 уже будет отличный квест, в котором нужно ликвидировать участников в определенном порядке с расстояния не менее 300 м. Но почему-то по этому конфигу в онлайне не оставались неписи группировки Монолит. Экологи, Бандиты, Военные - без проблем, а вот Монолитовцы - не хотят. И это сподвигло меня провести основательное исследование факта неухода некоторых неписей в оффлайн при удалении на расстояние, большее алайфа. И результатами этого исследования я хочу здесь с вами поделиться) Все действия выполнялись на алспауне последней Солянки. Я сделал следующее: поставил switch_distance = 0, выставил неуязвимость, начал НИ, заспавнил себе кучу телепортов и биорадар, подкрутил биорадар, чтобы он показывал всех на расстоянии 1000м и пошел гулять по Зоне) И при switch_distance=0 (в оффлайне) я обнаружил на локациях следующих неписей: Кордон: 4 собачки у грузовика, где НИ начинаем. Шустрый на АТП: esc_shustryi Сидор Весь блокпост военных на кордоне Свалка: Бандиты за стоянкой техники, от которых нужно помочь отбиться Бесу. Они под смартом gar_bandit_agr Бар: Захар и его 3 охотника, что трутся возле него в зеленых плащах, stalker_green_zahar. они под смартом bar_ohotnik. видать, Сяк скопировал его со смарта бандитов выше, ибо поведение идентичное) Вот, нашел кое что интересное: Южный блокпост бара у рва спавнился у меня примерно в 200 м и исчезал также. это секции неписей серии bar_zastava_guard_. Я копнул и нашел вот что: Он под смартом bar_zastava. Я глянул этот смарт и нашел в файле gulag_bar.script по каждому из неписей из этого гулага такую строку: online = "{=actor_in_zone(bar_zastava_online_restrictor)}", я глянул этот рестриктор в алспауне. вот он: [3484] ; cse_abstract properties section_name = space_restrictor name = bar_zastava_online_restrictor position = 248.094848632813,1.75414443016052,-57.0616226196289 direction = -0.0448038317263126,0.00183825858402997,0.0110875321552157 ; cse_alife_object properties game_vertex_id = 1168 distance = 0 level_vertex_id = 76465 object_flags = 0xffffff3e ; cse_shape properties shapes = shape0 shape0:type = box shape0:axis_x = 130,0,0 shape0:axis_y = 0,20,0 shape0:axis_z = 0,0,230 shape0:offset = 0,0,0 ; cse_alife_space_restrictor properties restrictor_type = 3 Обратите внимание, что он в форме бокса размером x=130,x=20,z=230 м. И рестриктор этот заспавнен перед постом, в районе рва. То есть при приближении к этому рестриктору по координате z менее чем на 230 метров происходит спавн блокпоста. Это при том, что алайф у меня стоит в НОЛЬ! и в игре он стоит в 160! Я здесь подкрутил биорадар, чтобы он показывал спавн на 250 м, и действительно, при приближении по дороге со Свалки примерно на 200 м на биорадаре появляются 4 точки. чуть отошел - точки исчезли. То есть при такой конструкции смарта, как здесь - он спавнится не по алайфу, а по рестриктору. И я уверен, что если здесь поставить вместо 230 м 350 м, то смарт заспавнится за 350 м от гг. Аналогично и северный блокпост: там стоит рестриктор [3486] ; cse_abstract properties section_name = space_restrictor name = bar_zastava2_online_restrictor position = 67.0966644287109,0,137.509429931641 direction = 0,0,0 ; cse_alife_object properties game_vertex_id = 1168 distance = 0 level_vertex_id = 76465 object_flags = 0xffffff3e ; cse_shape properties shapes = shape0 shape0:type = box shape0:axis_x = 70,0,0 shape0:axis_y = 0,20.2800006866455,0 shape0:axis_z = 0,0,50 shape0:offset = 0,0,0 ; cse_alife_space_restrictor properties restrictor_type = 3 но тут разница в том, что у него размеры меньше алайфа - 70х20х50. Но я протестировал его более тщательно. И у меня - внимание: И НА ТЕСТЕ со switch_distance=0 И НА ИГРЕ со switch_distance=160 северный блокпост ВСЕГДА СПАВНИЛСЯ ТОЛЬКО ПРИ ВХОДЕ В РЕСТРИКТОР! независимо от расстояния алайф! Можно легко самому в этом убедиться. Обойдите с другой стороны ворота, где переход на ДТ, выйдя за локу в Баре, наденьте биорадар и подходите потихоньку к воротам, в которых переход. Сами увидите, в какой момент будет спавниться северный блокпост - как раз на расстоянии примерно в 60 м. Момент спавна даже в бинокль можно увидеть через дыру в воротах) И в Баре почти весь спавн неписей еще с оригинала сделан подобным образом, через рестрикторы, не через алайф. И еще: в файле gulag_escape.script я нашел такую строку (правда, она закомментена): -- online = true, а что будет, если ее раскомментить? или, выше, вместо online = "{=actor_in_zone(bar_zastava_online_restrictor)}", написать online = true, ? Я не пробовал, но почему-то уверен, что тогда все неписи в этом гулаге, для которых будет выставлен такой параметр, будут в онлайне всегда, пока гг будет находиться на этой локе, независимо от расстояния до них... Далее, в Баре всегда в онлайне Доцент. А Долговязый - нет. Я сравнил их конфиги. У них предикаты не такие, как у вояки на АС, но у обоих одинаковые. А вот флажки - разные. У доцента: object_flags = 0xffffff7b или 1101111011, у Долговязого: object_flags = 0xffffffbf или 1110111111. Как видим, у Доцента снят флаг перехода в оффлайн и привязки к аи сетке. И он - всегда в онлайне... Значит, этот конфиг тоже можно использовать для поставленной задачи) На АС, кроме уже упомянутого выше снайпера, постоянно в онлайне гулаг Долга во главе с Черепом, а также небольшая разборка между сталкерами, которую мы встречаем при самом первом заходе на АС. И, как я к этому моменту уже предполагал, На радаре я встретил Монолитовца, который также постоянно был в онлайне, пока я был на локе. Это снайпер на антенне выжигателя на Радаре. У него нет смарта и нет рестрикторов - просто спавн с привязкой к точке. Это rad_antenna_sniper1 в alife_l10_radar.ltx. Припять: всегда в онлайне группа сталкеров, которая встречает ГГ при первом заходе в Припять. ЧАЭС1: всегда в онлайне блокопст монолита у входа на ЧАЭС, а также 2 монолитовца с РПГ: aes_stalker_0011 и aes_stalker_0009. Так, что вариантов конфигов для неписей более чем достаточно) Там еще есть другие монолитовцы с ГПР, character_profile = aes_Monolit_rpg, но у них у всех, кроме этих двух стоит тэг spawner. Я принудительно выдал указанные там поршни (aes_actor_btr и aes_desant_wave3) и они сразу появились. Не забываем, что switch_distance по прежнему = 0)) Расстояние до них от места, где я выдал эти поршни - 270-300 м. Также постоянно в онлайне ходит военный, у которого забираем сумку Сахарова. На ЧАЭС2 также полно "вечно онлайновых" Монолитовцев. У меня было 5 штук: aes2_stalker_0002, aes2_stalker_0003, aes2_stalker_0008, aes2_stalker_0010, aes2_stalker_0011 Так что, используя эти конфиги, вполне реально делать снайперские квесты на отстрел неписей на большом расстоянии. А чтобы гг не подбирался к ним ближе, обозначаем ему рестриктором зону, из которой он должен выполнить задание, и проваливаем задание при выходе из рестриктора) Изменено 3 Января 2013 пользователем proper70 4 1 Ссылка на комментарий
ColR_iT 171 Опубликовано 3 Января 2013 Поделиться Опубликовано 3 Января 2013 proper70 И еще: в файле gulag_escape.script я нашел такую строку (правда, она закомментена):-- online = true, а что будет, если ее раскомментить? Этот параметр, в некотором смысле, аналогичен секции spawner в custom_data. Т.е. если стоят условия, то он определяет параметры выхода в онлайн, если же поставить true, то любой НПС будучи на данной работе всегда будет находиться в онлайне.В целом информация очень интересная. От меня лично - благодарю. Ссылка на комментарий
Viнt@rь 50 Опубликовано 3 Января 2013 Поделиться Опубликовано 3 Января 2013 (изменено) Artos, спасибо за пояснение , в общем, можно смело использовать метод w_float и не париться... ЗЫ такие большие числа мне уж точно запоминать не надо))) ColR_iT, с планшета писал, потому и забыл про клавишу shift Изменено 3 Января 2013 пользователем Viнt@rь GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
lsclon 527 Опубликовано 3 Января 2013 Поделиться Опубликовано 3 Января 2013 proper70 используя эти конфиги На самом деле, управление онлайном контролируют всего два параметра в аллспавне. Первое - это object_flags. То есть флаг, имеющий на конце a или b - всё время в онлайне. C или d - всё время в оффлайне. E или f - онлайн работаем, оффлайн не движемся. Второе - это distance. Число, записанное там, увеличивает алайф дистанцию. Что касается Бара, военных на Кордоне и т.д. - всё это работа смарта. То есть, у них в работе прописано online = true, что значит всегда быть в онлайне. Либо online = false, что значит работаем в оффлайне. Рестрикторы всего лишь переключают это состояние. Кстати по флагам - есть два интересных флага 07 и 37. Они заставляют нпс в упор не замечать владельца такого флага, с одной лишь разницей, что 37 действует до попадания к ГГ в рюкзак. Достаточно вспомнить банку энергетика у костра в Деревне новичков, которая может проваляться всю игру. P.S. Насчёт предикатов интересно, надо будет посмотреть. 1 Вообще-то я белая и пушистая... Ссылка на комментарий
Viнt@rь 50 Опубликовано 4 Января 2013 Поделиться Опубликовано 4 Января 2013 (изменено) Плз хелп, решил сделать "упрощенное"(даже очень упрощенное) хранилище своих данных, на основе наработок xStream и Malandrius... вот содержимое скрипта - хранилища: --]] --------------------------------------------------------------------------------------------------/ Variables--]] ------------------------------------------------------------------------------------------------storage = {}local save_markers = {}local bStReglocal type2marker = {['boolean'] = 1,['number'] = 2,['string'] = 3,['table'] = 4}local marker2type = {[1] = 'boolean',[2] = 'number',[3] = 'string',[4] = 'table'}--]] --------------------------------------------------------------------------------------------------/ Initialize--]] ------------------------------------------------------------------------------------------------function Init()event("ActorSave"):register(CreateStorageObj)end--]] --------------------------------------------------------------------------------------------------/ Callback`s--]] ------------------------------------------------------------------------------------------------function CreateStorageObj()if not bStReg thenlocal oStorage = alife():create("custom_storage", vector(), 0, 0)-- никогда не выйдет в онлайнoStorage:can_switch_online(false)oStorage:can_switch_offline(true)bStReg = trueendend--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-- * se_custom_storage *--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *class "se_custom_storage" (cse_alife_dynamic_object)function se_custom_storage:__init(section) super(section)endfunction se_custom_storage:on_register()cse_alife_dynamic_object.on_register(self)bStReg = trueendfunction se_custom_storage:STATE_Read(packet, size)cse_alife_dynamic_object.STATE_Read(self, packet, size)_printf("Storage Load")while not packet:r_eof() dolocal k = packet:r_stringZ()_printf("Load Key:[%s]",tostring(k))LoadValue = function(tbl)local vlocal tv = marker2type[packet:r_u8()]if tv == 'string' thenv = packet:r_stringZ()elseif tv == 'boolean' thenv = packet:r_bool()elseif tv == 'number' thenv = packet:r_float()elseif tv == 'table' thenv = {}local n = packet:r_u8()local b = packet:r_bool()if n > 0 thenif b thenfor i = 1, n doLoadValue(v[i])endelsefor i = 1, n dolocal kk = packet:r_stringZ()LoadValue(v[kk])endendendendtbl = vendLoadValue(storage[k])endalife():release(self)event("StorageLoad"):trigger(--[[{packet = packet}--]])endfunction se_custom_storage:STATE_Write(packet)cse_alife_dynamic_object.STATE_Write(self, packet)_printf("Storage Save")event("StorageSave"):trigger(--[[{packet = packet}--]])if next(storage) thenfor k,v in pairs(storage) dopacket:w_stringZ(k)_log_db("Save Key:[%s]",tostring(k))SaveValue = function(Value)local tv = type(Value)if type2marker[tv] thenpacket:w_u8(type2marker[tv])if tv == 'string' thenpacket:w_stringZ(Value)elseif tv == 'boolean' thenpacket:w_bool(Value)elseif tv == 'number' thenpacket:w_float(Value)elseif tv == 'table' thenpacket:w_u8(#Value)packet:w_bool(IsList(Value))if IsList(Value) thenfor i = 1, #Value doSaveValue(Value[i])endelsefor kk,vv in pairs(Value) dopacket:w_stringZ(kk)SaveValue(vv)endendendelse_log_db("Save:->:<!Warning!>:->:Do not save type:=[%s]",tv)endendSaveValue(v)endendend-- этот объект всегда будет сохранятьсяfunction se_custom_storage:can_save()return trueend--]] --------------------------------------------------------------------------------------------------/ Functions--]] --------------------------------------------------------------------------------------------------[[-- Проверка типа таблицы:'список' или нет?-- @param table tTbl таблица-- @return boolean--]]function IsList(tTbl)local bList = falselocal iCntIdx = #tTblif iCntIdx > 0 thenif next(tTbl) == 1 and not next(tTbl,iCntIdx) thenfor i=2,iCntIdx-1 doif tTbl[i] == nil thenreturn falseendendbList = trueendendreturn bListend В итоге, вроде бы и сохраняет и загружает переменные нормально, но, если глянуть на выводимые логи сейва/загрузки, то получается что то странное, сохраняет переменные из массива storage замечательно, ничего лишнего в лог не выводит: Storage Save Save Key:[iSleep] -- переменная Save Key:[iCntNrg] -- переменная Save Key:[spawnBar] -- переменная Save Key:[tTimers] -- таблица с под таблицами Save Key:[tActorStats] -- таблица с ключами Save Key:[iActScore] -- переменная Save Key:[FirstRun] -- переменная а вот при загрузке: Storage Load Load Key:[iSleep] -- переменная Load Key:[iCntNrg] -- переменная Load Key:[spawnBar] -- переменная Load Key:[tTimers] -- таблица с под таблицами aHigh & aLow, которые ниже, вместе с их ключами, они не должны быть тут, лог загрузки по идее должен быть такой же, как и лог сохранения... Load Key:[aHigh] Load Key:[type] Load Key:[int] Load Key:[args] Load Key:[id] Load Key:[once] Load Key:[func] Load Key:[rem] Load Key:[aLow] Load Key:[tActorStats] --таблица с ключами, которые ниже Load Key:[iHeadShots] Load Key:[iKnifeKills] Load Key:[iGrenadeKills] Load Key:[iVodkaCnt] Load Key:[iActScore] -- переменная Load Key:[FirstRun] -- переменная сравнив этот лог с логом сейва, видно, что лишнее... Изменено 4 Января 2013 пользователем Viнt@rь GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
Malandrinus 615 Опубликовано 4 Января 2013 Поделиться Опубликовано 4 Января 2013 Viнt@rь, а чем тебя не устраивает готовое решение? Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Viнt@rь 50 Опубликовано 4 Января 2013 Поделиться Опубликовано 4 Января 2013 (изменено) malandrinus, 1. ИМХО, готовое решение - слишком громоздкое, в смысле, лично для меня, мне не нужно столько разных методов и тп, мне хватит того, что я сделал, в итоге получилось "простенько и со вкусом" 2. захотелось самому сделать нечто подобное, поработать с нет-пакетами, саморазвитие и тп... Изменено 4 Января 2013 пользователем Viнt@rь GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
Artos 99 Опубликовано 5 Января 2013 Поделиться Опубликовано 5 Января 2013 Viнt@rь, извини за недоверие, но что-то терзают сомнения, что приведенный тобою код соответствует тому, на котором ты получал логи (имею ввиду чтение пакета). Встроенная функция LoadValue, которая читает и при рекурсивных вызовах суб-таблицы, никак не затрагивает строку вывода в лог, и т.о. никак не могут появляться строки о чтении ключей суб-таблиц. Такое возможно, если только строка для лога внутри этой функции. Аргумент по п.2 - вызывает желание сказать: "Молодец!", но... вот п.1 - ой как неоднозначен. Конечно, если задача ограничена и не подразумевает возможного расширения - то конечно нет смысла использовать "скрипт-монстр", но уж больно знакомая мне тема ;-), и после "учебы" аппетит вырастет и это приведет к желанию наращивать и усложнять функционал. Иными словами, при разработке нужно учитывать не свой аппетит "на сейчас", а и то, что ... а "вдруг в гости друг заглянет?", т.е. учитывать и возможные ситуации, которые тоже может потребоваться сейчас или в дальнейшем обеспечить работой разрабатываемого скрипта. "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Malandrinus 615 Опубликовано 5 Января 2013 Поделиться Опубликовано 5 Января 2013 Viнt@rь, слишком громоздкое, в смысле, лично для меня, мне не нужно столько разных методов и тп, Это сколько там методов? В обеих упомянутых системах интерфейс сводится фактически к двум функциям получить/записать переменную. Впрочем, дело твоё. Не совсем ясно, что именно ты взял за основу и какой версии, поскольку системы мои и xStream отличаются и общего имеют только класс объекта хранения. По любому, если самоцель - именно поковыряться внутри, то рекомендую взять за основу систему xStream. На мой субъективный взгляд её разбирать и менять проще. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Viнt@rь 50 Опубликовано 5 Января 2013 Поделиться Опубликовано 5 Января 2013 (изменено) malandrinus, сначала я разбирался в твоей системе)) потом в системе xStream, в итоге, думаю основную часть понял, а о методах, это я имел ввиду типа использования классов и функций из, xs_netpk, ogse_unist, и тп... за основу взял скрипт ogse_base_storage, а все остальные ваши наработки, послужили основой для более углубленного понятия, как работать и что можно делать с нет-пакетами. Изменено 5 Января 2013 пользователем Viнt@rь GUI для конвертера от бардака(всего и вся в форматы сдк) Полезный утиль-"Utilits pack(mod)" Ссылка на комментарий
proger_Dencheek 6 Опубликовано 6 Января 2013 Поделиться Опубликовано 6 Января 2013 Такая напасть случилась: Не работает death_callback, из bind_monster. Т.е. в статистику не записываются убитые монсты, не дается ранг за них, если в колбек поставить функцию - она не сработает и т.д... И если в логике монстра поставить on_death = ... это тоже не срабатывает. Колбеки и их функции не трогал. Мне остается только "танцевать с бубном". Подскажите хотя-бы примерную причину этого безобразия:-( Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти