naxac 2 447 Опубликовано 3 Ноября 2016 Поделиться Опубликовано 3 Ноября 2016 в какой момент начинается заполнение пакетаВ пстор при старте таймера пишется три перменных. Вот здесь они чистятся: amk.del_variable("rt"..i) amk.del_variable("rt"..i.."d") amk.del_variable("rt"..i.."p") amk.del_variable("gt"..i) amk.del_variable("gt"..i.."d") amk.del_variable("gt"..i.."p") rt* - реального времени, gt* - игрового. 2 Аддон для ОП-2.09.2: Яндекс/Google/GitHub Ссылка на комментарий
CRAZY_STALKER666 36 Опубликовано 8 Ноября 2016 Поделиться Опубликовано 8 Ноября 2016 Такая проблема: вот логика НПЦ [logic] active = remark@1 on_hit = hit [remark@1] target = actor no_move = true [remark@2] target = actor no_move = true [hit] on_info = {+gauss_online} remark@2 %+sar_brut_death =make_suicide% on_info2 = %+sar_brut_death =make_suicide% Вот сама функция, которая должна выполняться: function make_suicide(actor, npc) news_manager.send_tip(db.actor, "триггер смерти", nil, nil, 20000) npc:kill(npc) end Но она не выполняться. Ни одно из условий в hit не работет. Как так то? UPD1. Такое дело - НПЦ бессмертный, ему выставлены конфиги иммунитета наподобие Сахарова. Делаю вывод - хиты просто по нему не проходят. Сделал его смертным - всё заработало. Нашел xr_hit.script дабы сделать передачу id стрелка, даже если дамаг = 0. Что я там только не делал, даже в xr_motivator заглянул. Не помогло, хотя там есть строчки с комментариями мол дамага 0, игнорим... А что-то сделать нужно! Не соответствует правилам. Ссылка на комментарий
CRAZY_STALKER666 36 Опубликовано 11 Ноября 2016 Поделиться Опубликовано 11 Ноября 2016 Ребятки, проконсультируйте. Тут совсем нетривиальная проблема. В отдельном файле объявил переменную. Допустим в test_scr объявил - local test = 0 Из другого в теле какой-либо функции : test_scr.test = 1 В итоге после проверки всё равно test равен 0 Где я ошибся? Не соответствует правилам. Ссылка на комментарий
TIGER_VLAD 361 Опубликовано 11 Ноября 2016 Поделиться Опубликовано 11 Ноября 2016 @CRAZY_STALKER666, создай глобальную переменную, просто : test = 0 Ссылка на комментарий
CRAZY_STALKER666 36 Опубликовано 11 Ноября 2016 Поделиться Опубликовано 11 Ноября 2016 @TIGER_VLAD, не изменилось ничего... Не соответствует правилам. Ссылка на комментарий
mortan 143 Опубликовано 11 Ноября 2016 Поделиться Опубликовано 11 Ноября 2016 @CRAZY_STALKER666, так важно ещё в какой области ты переменную объявляешь - мб она у тебя перезаписывается последующим вызовом скрипта. Ссылка на комментарий
Serge! 127 Опубликовано 11 Ноября 2016 Поделиться Опубликовано 11 Ноября 2016 (изменено) Допустим в test_scr объявил - local test = 0 Из другого в теле какой-либо функции : test_scr.test = 1 В итоге после проверки всё равно test равен 0 Файл test_scr.script _G.test = 0 Файл sample.script test = 1 Изменено 11 Ноября 2016 пользователем Serge! Ссылка на комментарий
Kober(BRUC) 99 Опубликовано 13 Ноября 2016 Поделиться Опубликовано 13 Ноября 2016 Добрый день. Есть фон(background) и на нём статик(icon): xml:InitStatic("background:icon", self.background) Как мне этому статику поменять текстуру по условию при открытии этого окна? С помощью конструктора(ООП)? Ссылка на комментарий
Serge! 127 Опубликовано 14 Ноября 2016 Поделиться Опубликовано 14 Ноября 2016 (изменено) Как мне этому статику поменять текстуру по условию при открытии этого окна? Раз за почти 12 часов реального времени на этот пустяшный вопрос из корифеев никто не ответил, попробую я, игзой. Это не только просто, а просто очень просто. Во сказал! Здесь возможны 2 варианта реализации, при любом из которых вы должны иметь готовые текстуры всех статиков. Если Вы являетесь ярым сторонником xml, то смотрите вариант 1. Если же Вам все едино, "что камым, что Колыма", то вариант 2. Ремарка: Я сильно смеялся тут недавно, когда читал (где уже не помню) дискуссию сторонников и противников xml и скриптового подходов в скриптинге. Ну дети прямо, прости меня Всевышний. Не вмешивался потому, что "висел" тогда на 99% наказаний, а, если бы встрял, то точно был бы отлучён от тела этого ресурса. Да и сейчас эту тему развивать не буду. Исходим из того, что имеется xml файл описания текстур (если Вы не знаете, что это такое, то дальше читать вообще не имеет смысла) В xml файле описания окна прописываете несколько разных тегов вашего статика: <background> <icon_1 [нужные вам агрументы]> <texture>icon1</texture> </icon_1> <icon_2 [нужные вам агрументы]> <texture>icon2</texture> </icon_2> <icon_3 [нужные вам агрументы]> <texture>icon3</texture> </icon_3> </background> В файле скрипта окна пишите: if условие_1 then xml:InitStatic("background:icon_1", self.background) elseif условие_2 then xml:InitStatic("background:icon_2", self.background) elseif условие_3 then xml:InitStatic("background:icon_3", self.background) end Это всё. Это чисто скриптовое решение. Файл xml не требуется. Предполагается, что все ваши текстуры находятся в отдельных файлай dds и находиться в папке texture/ui. Можно их объединить и в один. Это увеличит код на пару строк. Каких сообразите сами, или подождите пару месяцев (с меня снимут необонованные штрафы и я опубликую коды пакета графических примитивов UI, которые легко решают все подобные проблемы) тогда Вам и это не понадобится. Итак, приступаем. В файле скрипта окна пишите: local icon = CUIStatic() -- автоудаление можно не задавать т.к. мы объявили её локальной background:AttachChild(icon) icon:Init([инициализируем позицию и размеры]) if условие_1 then icon:InitTexture("ui\\icon_1") elseif условие_2 then icon:InitTexture("ui\\icon_2") elseif условие_3 then icon:InitTexture("ui\\icon_3") end icon:SetStretchTexture(true) -- подгоняем текстуру под заданные параметры Вы будете смеяться, но это опять всё. А про ООП в Сталкере и Lua забудьте. Здесь нет классов в обычном их понимании. Есть псевдоклассы (я ими тоже широко пользуюсь), но это совсем другая песня. В конструкторы классов движка можно попасть только через исходники (они есть) или другими извращениями, но это, для Сталкера, путь в никуда, как-бы некоторые себя этим не тешили. Удачи. Изменено 14 Ноября 2016 пользователем Serge! 1 Ссылка на комментарий
CRAZY_STALKER666 36 Опубликовано 14 Ноября 2016 Поделиться Опубликовано 14 Ноября 2016 По проблеме из поста #8024. На бессмертных НПЦ не срабатывала схема xr_hit. Вот полный скрипт нового xr_hit. Вдруг кто еще с такой проблемой столкнется... class "action_process_hit"function action_process_hit:__init(obj, storage)self.object = objself.st = storageendfunction action_process_hit:hit_callback(obj, amount, local_direction, who, bone_index)--if amount == 0 then-- FIXME if_then_else-- --printf("[%s] hit by [%s]: 0 damage, ignoring", obj:name(), if_then_else(who, who:name(), ""))---db.storage[obj:id()].hit.who = who:id()--return--endif who or amount == 0 thenprintf("[%s] hit by [%s]", obj:name(), who:name())news_manager.send_tip(db.actor, "!!"..obj:name().." hit by "..who:name().."!!", 0, "default", 10000)db.storage[obj:id()].hit.who = who:id()elseprintf("[%s] hit by [unknown]", victim:name())db.storage[obj:id()].hit.who = -1endif db.storage[self.object:id()].active_scheme thenif xr_logic.try_switch_to_another_section(obj, self.st, db.actor) thenreturnendendend------------------------------------------------------------------------------------------------------------------------ binder----------------------------------------------------------------------------------------------------------------------function add_to_binder(npc, ini, scheme, section, storage)local new_action = this.action_process_hit(npc, storage)storage.action = new_actionendfunction set_hit_checker(npc, ini, scheme, section)local st = xr_logic.assign_storage_and_bind(npc, ini, scheme, section)st.logic = xr_logic.cfg_get_switch_conditions(ini, section, npc)-- НЕ СТАВИТЬ hit callback напрямую - получаем его из motivator-а через-- event в подписанном на него action-е:--npc:set_callback(callback.hit, st.action.hit_callback, st.action)xr_logic.subscribe_action_for_events(npc, st, st.action)endfunction disable_scheme(npc, scheme)-- При отключении схемы, нужно снять подписку, чтобы hit callback перестал-- передаваться:--npc:set_callback(callback.hit, nil)local st = db.storage[npc:id()][scheme]if st thenxr_logic.unsubscribe_action_from_events(npc, st, st.action)endend Добавлено Kirgudu, 14 Ноября 2016 Ссылки вида #8024 давать бессмысленно. Один спереди удалённый пост, и всё съезжает. Вот и сейчас пост #8024 - от naxac. Добавлено Kirgudu, 14 Ноября 2016 Для получения правильной ссылки следует нажать мышью на этот номер. Или использовать цитирование (соблюдая правила, конечно). Не соответствует правилам. Ссылка на комментарий
CRAZY_STALKER666 36 Опубликовано 15 Ноября 2016 Поделиться Опубликовано 15 Ноября 2016 Такие вопросы: 1. Каков номер слота под артефакты в ТЧ. Пробовал 0, -1. В system.ltx вообще упоминания не нашел, да и там пояснения к слотам какие-то неверные... 2. Как соранить набор вещей ГГ, а потом выдать их ему в ящике? Знаю, что так работает Арена, но я немного не разобрался... Не соответствует правилам. Ссылка на комментарий
naxac 2 447 Опубликовано 15 Ноября 2016 Поделиться Опубликовано 15 Ноября 2016 @CRAZY_STALKER666, 1. Если ты имеешь в виду пояс, то пояс - это не слот, и номера у него нет. А активировать артефакт можно из первого или второго слота. Может, и из других тоже. 2. actor:transfer_item(item, box) где item - предмет, box - ящик. Например так function transfer_all_to_box() local box = level_object_by_sid(12345) -- 12345 - стори-ид ящика db.actor:iterate_inventory(function (actor, item) actor:transfer_item(item, box) end, db.actor) end 1 1 Аддон для ОП-2.09.2: Яндекс/Google/GitHub Ссылка на комментарий
CRAZY_STALKER666 36 Опубликовано 15 Ноября 2016 Поделиться Опубликовано 15 Ноября 2016 Тогда перефразирую вопрос - как отследить появление определенного артефакта на поясе у ГГ? Не соответствует правилам. Ссылка на комментарий
UnLoaded 313 Опубликовано 15 Ноября 2016 Поделиться Опубликовано 15 Ноября 2016 как отследить появление определенного артефакта на поясе у ГГ? Движковой ф-ции для этого в ТЧ нет. Вроде есть какой-то костыльно-скриптовый способ отследить объекты на поясе, если память не подводит - от Kirgudu. Спроси у него... Ссылка на комментарий
naxac 2 447 Опубликовано 15 Ноября 2016 Поделиться Опубликовано 15 Ноября 2016 @CRAZY_STALKER666, если мне склероз не изменяет, то: Надо заспавнить в инвентарь предмет и потом перебирать инвентарь через iterate_inventory. Предметы, которые будут передаваться в итератор после заспавненного, будут либо в слотах, либо на поясе. Проверяешь их - если не в слоте, значит на поясе. Далее сверяешь то, что получилось с тем, что было на предыдущей проверке. В солянке, по крайней мере, используется такой метод - файл inventory.script. Единственное - именно момент перемещения предмета на пояс не отловить. А в проекте X-Ray Extensions добавлены каллбэки для актера на перемещение предметов между слотами, рюкзаком и поясом. Аддон для ОП-2.09.2: Яндекс/Google/GitHub Ссылка на комментарий
Kober(BRUC) 99 Опубликовано 15 Ноября 2016 Поделиться Опубликовано 15 Ноября 2016 @CRAZY_STALKER666, дополню пост naxac'а. А точнее содержание файла: need_update = true local belt = {} local belt_id = {} local belt_status = false local inventory_open = false local separator_spawned = false local separator = "separator" local af_idol_monolita_on_belt = false local debug = false local flag function update() if (need_update == false) or has_alife_info("paused_on_load") then return end if debug == true and belt_status == true then get_console():execute("belt_status=false") end belt_status = false -- Спавним разделяющий елемент if (separator_spawned == false) then alife():create(separator, db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id()) separator_spawned = true if debug == true then get_console():execute("separator_spawned") end return end belt = {} belt_id = {} flag = 0 -- Сканируем инвентарь db.actor:inventory_for_each(scan_inv) -- вместо количества теперь идет проверка по иммунитетам -- remove_duplicate() check_immunities() check_idol_monolita() need_update = false -- Удаляем разделяющий елемент db.actor:inventory_for_each(del_separator) separator_spawned = false if debug == true and belt_status == false then get_console():execute("belt_status=true") end belt_status = true if debug == true then for i,k in pairs(belt) do get_console():execute(i.."="..k) end end end -- Перебор предметов инвентаря function scan_inv(item) local section = item:section() if section == separator then flag = 1 return end if flag == 1 then if slot_item(item) ~= nil then flag = 2 else insert_to_table(belt, section) belt_id[item:id()] = true end end end -- Добавление в таблицу function insert_to_table(tbl, section) if tbl[section] == nil then tbl[section] = 1 else tbl[section] = tbl[section] + 1 end end -- Удаление из таблицы function remove_from_table(tbl, section) if tbl[section] == 1 then tbl[section] = nil else tbl[section] = tbl[section] - 1 end end -- Удаление разделяющего предмета function del_separator(item) if item:section() == separator then alife():release(alife():object(item:id()), true) if debug == true then get_console():execute("separator_removed") end end end -- Определение налечия предмета в одном из слотов function slot_item(item) for i=0,12 do local obj = db.actor:item_in_slot(i) if obj and item:id() == obj:id() then return i end end return nil end -- Поднятие предмета function on_item_take(item) if item:section() == separator then return end if (inventory_open == false) then if (separator_spawned == true) then db.actor:inventory_for_each(del_separator) separator_spawned = false end need_update = true if debug == true then get_console():execute("item_take") end end end -- Выброс предмета function on_item_drop(item) if item:section() == separator then return end if (inventory_open == false) then if (separator_spawned == true) then db.actor:inventory_for_each(del_separator) separator_spawned = false end need_update = true if debug == true then get_console():execute("item_drop") end end end -- Открытие/закрытие инвентаря function on_inventory_info(info_id) if info_id == "ui_inventory" then inventory_open = true if debug == true then get_console():execute("inventory_open") end elseif info_id == "ui_inventory_hide" then inventory_open = false need_update = true if debug == true then get_console():execute("inventory_close") end end end --[[ function check_blood() -- if belt_status == true then if belt["af_blood"]~=nil and belt["af_blood"]>0 then -- то есть когда параметр пояса[af_blood] равен 1, 2, 3.. Сколько навесишь Камней. amk.send_tip("Кровь Камня на поясе") end -- end end ]] --[[ local unique_sect = { ["af_caterpillar"] = true, ["af_arhara_globus"] = true, ["af_vyvert_green"] = true, ["af_blood_green"] = true, ["af_dummy_spring_red"] = true, ["af_dummy_battery_red"] = true, ["af_dummy_pellicle_red"] = true, ["af_babka_3"] = true, ["af_babka_4"] = true, ["af_armor_4"] = true, ["af_cry_3"] = true, ["af_dik_4"] = true, ["af_kol_3"] = true, ["af_kol_4"] = true, ["af_pudd_4"] = true, ["af_spirit_3"] = true, ["af_spirit_4"] = true, ["af_gold_fish"] = true, ["af_eye_voron"] = true } --оставляет на поясе по одному(фиг,теперь двум) артефакту каждого вида function remove_duplicate() local t = check_duplicate() for k, v in pairs(belt_id) do local sobj = alife():object(k) if sobj then local sect = sobj:section_name() --if is_unique(sobj:clsid()) and t[sect] ~= nil and t[sect] > 0 then --if is_unique(sect) and t[sect] ~= nil and t[sect] > 0 then if unique_sect[sect] and t[sect] ~= nil and t[sect] > 0 then alife():release(sobj, true) local text="Убраны лишние артефакты "..game.translate_string(amk.get_inv_name(sect)).." с пояса" news_manager.send_tip(db.actor, text, nil, nil, nil) amk.spawn_item_in_inv(sect, db.actor) t[sect] = t[sect] - 1 end end end end --собирает инфу о дупликатах на поясе --возвращает таблицу вида [секция арта] = <количество лишних артов> function check_duplicate() local result = {} for k, v in pairs(belt) do if v > 2 then result[k] = v - 2 end end return result end ]] --возвращает true, если предмет должен быть на поясе в единственном числе --function is_unique(section) --[[local result = false for i=1,table.getn(unique_sect) do if section == unique_sect[i] then result = true break end end]] --return (section ~= nil and unique_sect[section] == true) --return result --end -- Проверка на иммунитеты и удаление с пояса лишних артов local imm_limits = {100, 86, 73, 60} local imm_limit, sobj, sect, imm_sect, bad_imm local immunities = { {sect="burn_immunity",name="Ожог",total=0}, {sect="strike_immunity",name="Удар",total=0}, {sect="shock_immunity",name="Электрошок",total=0}, {sect="wound_immunity",name="Разрыв",total=0}, {sect="radiation_immunity",name="Радиация",total=0}, {sect="telepatic_immunity",name="Телепатия",total=0}, {sect="chemical_burn_immunity",name="Химический ожог",total=0}, {sect="explosion_immunity",name="Взрыв",total=0}, {sect="fire_wound_immunity",name="Пулестойкость",total=0} } function check_immunities() if db.actor:object("af_invul") then return end imm_limit = imm_limits[level.get_game_difficulty()+1] repeat -- считаем иммунитеты total_immunities() -- проверяем иммунитеты bad_imm = bad_immunity() if bad_imm then -- есть перебор в иммунитете - удаляем лишний арт и вновь считаем иммунитеты imm_remove_art(bad_imm) else -- все ок break end until false end function imm_remove_art(imm) for k, v in pairs(belt_id) do sobj = alife():object(k) if sobj then sect = sobj:section_name() imm_sect = rx_utils.read_from_ini(nil, sect, "hit_absorbation_sect", nil, 1) if imm_sect and rx_utils.read_from_ini(nil, imm_sect, immunities[imm].sect, 1, 3) < 1 then -- арт увеличивает иммунитет alife():release(sobj, true) amk.spawn_item_in_inv(sect, db.actor) remove_from_table(belt, sect) belt_id[k] = nil news_manager.send_tip(db.actor, "Для текущего уровня сложности создаваемый артефактами имммунитет "..immunities[imm].name.." не должен превышать "..tostring(imm_limit).."%. Артефакт "..game.translate_string(amk.get_inv_name(sect)).." убран с пояса.", nil, "nano", 20000) return end end end end function bad_immunity() for i=1,#immunities do if immunities[i].total > imm_limit then return i end end return nil end function total_immunities() for i=1,#immunities do immunities[i].total = 0 end for k, v in pairs(belt_id) do sobj = alife():object(k) if sobj then sect = sobj:section_name() imm_sect = rx_utils.read_from_ini(nil, sect, "hit_absorbation_sect", nil, 1) if imm_sect then -- считаем иммунитеты for i=1,#immunities do immunities[i].total = immunities[i].total+100-math.floor(rx_utils.read_from_ini(nil, imm_sect, immunities[i].sect, 1, 3)*100+0.1) end end end end end -- предмет на поясе function on_belt(sect) return belt[sect] end function items_on_belt() local count = 0 for k,v in pairs(belt) do count = count+v end return count end function is_free_belt_slot() return items_on_belt() < rx_utils.read_from_ini(nil, "inventory", "max_belt", 1, 3) end function get_free_belt_slot() if is_free_belt_slot() then return end local sect for k,v in pairs(belt_id) do sect = level.object_by_id(k):section() if not string.find(sect, "bioradar") and sect ~= "af_invul" and rx_utils.read_from_ini(nil, sect, "class", "", 1) ~= "D_SIMDET" then alife():release(alife():object(k), true) amk.spawn_item_in_inv(sect, db.actor) remove_from_table(belt, sect) belt_id[k] = nil return end end end -- Идол Монолита на поясе function check_idol_monolita() if not has_alife_info("snp_shadows_start") or has_alife_info("snp_shadows_done") then return end if belt["af_idol_monolita"] then if not af_idol_monolita_on_belt then -- одели арт af_idol_monolita_on_belt = true level.set_weather("grey") end else af_idol_monolita_on_belt = false end end Ссылка на комментарий
CRAZY_STALKER666 36 Опубликовано 15 Ноября 2016 Поделиться Опубликовано 15 Ноября 2016 Большое спасибо! Но увы, такие дикие костыли использовать не могу в моде, народ обидеться) Не соответствует правилам. Ссылка на комментарий
Serge! 127 Опубликовано 15 Ноября 2016 Поделиться Опубликовано 15 Ноября 2016 (изменено) @CRAZY_STALKER666, Зря Вы так резко отмахиваетесь. Метод void inventory_for_each(function *iterator) это не единственный, но в вашем случае самый оптимальный способ решить свои проблемы. Разумеется в приведёном примере надо выкинуть98% кода, но такой подход активно используется в модах. Вы же не думаете, что являетесь единственным, кто сталкивался с такой задачей? Изменено 15 Ноября 2016 пользователем Serge! Ссылка на комментарий
CRAZY_STALKER666 36 Опубликовано 16 Ноября 2016 Поделиться Опубликовано 16 Ноября 2016 (изменено) Разумеется в приведёном примере надо выкинуть98% кода, но такой подход активно используется в модах. Вы же не думаете, что являетесь единственным, кто сталкивался с такой задачей? Ладно, объясню. Любому методу можно найти замену. И я нашел, в моем случае артефакт просто работает из рюкзака(что вполне реалистично), а скрипты лишний раз не грузят апдейт актора. И да, знаю что не я 1 с этим сталкивался. Но раз суть проблемы такова - подойдем к ней с другой стороны. Не в обиду автора сего кода, но костыли использовать не очень хочется. Ну понятно дело без них никак, но чем меньше тем лучше. Изменено 16 Ноября 2016 пользователем CRAZY_STALKER666 Не соответствует правилам. Ссылка на комментарий
Serge! 127 Опубликовано 16 Ноября 2016 Поделиться Опубликовано 16 Ноября 2016 (изменено) костыли использовать не очень хочется Вы мне не объясните, что такое "костыли"? Я понимаю, что это какой-то местный сленг, просто хотелось бы точно знать его значение, чтобы понять суть проблемы. А по существу? Вы пошли своим путём, на мой взгляд не самым оптимальным, но это не очень важно. Главное Вы сами нашли решение. это замечательно. Изменено 16 Ноября 2016 пользователем Serge! Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти