antihumanist 0 Опубликовано 27 Октября 2014 Всем доброго времени ссуток. После прохождения SoC(1.0006) мне захотелось сделать некоторые не архисложные модификации игры : Начну с того что проходя вышеупомянутую часть сталкера мне не удалось заполучить одну редкую винтовку.. Уже после прохождения игры я наткнулся на тутор как прописать игроку в рюкзак предметы скриптом. Теперь внимание вопрос: Как игра подключает скрипты ? т.е. как заинклюдить свой пользовательский файл со скриптом чтобы он был виден из других скриптов ? Чтобы вызвать его к примеру из S.T.A.L.K.E.R - Shadow of Chernobyl\gamedata\scripts\ui_main_menu.script -- if dik == DIK_keys.DIK_S then-- self:OnButton_load_spawn() -- else if dik == DIK_keys.DIK_Q then self:OnMessageQuitWin()--после этого elseif db.actor~=nil and dik==DIK_keys.DIK_F4 then add_all_Wpn()--Моя функция которую я хочу иметь в своем скрипте а не дописывать их в конец уже имеющегося игрового скрипта, так как такой способ я считаю неправильным или просто нехорошим P.S.Я тут новенький так что если что не так то прошу тапками не кидать.Туторы читал и там не нашел такой инфы. Поделиться этим сообщением Ссылка на сообщение
antihumanist 0 Опубликовано 23 Августа 2015 (изменено) Немогу понять почему не работает скрипт.По задумки при сбросе рюкзака он должен заполнятся инвентарем актора, делаю для теста что-бы понять как это все потом сделать в другом моде. файл bind_stalker.script function actor_binder:update(delta) object_binder.update(self, delta) -- DEBUG slowdown -- slowdown.update() local time = time_global() game_stats.update (delta, self.object) --*************************************************** -->>Treasure rucksack 1/2--- вот рабочий код сбрасываемого рюкзака, брал из википедии сталкера, этот код работает поэтому полностью его не привожу if self.rr_id~=nil then--то что мы записали при дропе -- пытаемся получить объект по id local se_obj=alife():object(self.rr_id) -- проверяем, что объекта нет if se_obj==nil or se_obj:section_name()~="inv_ruck" then local ruck=alife():create("active_ruck", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id()) level.map_add_object_spot_ser(ruck.id, "red_location", "%c[255,238,155,23]Моя нычка для хабара") news_manager.send_tip(db.actor, "Тайник заложен.", nil, nil, 5000) --obj_ruck = ruck--это типа переменной для теста с таймером --Start_Timer_5_minutes()--подумал что может не успевает отработать, но с таймером та-же байда my_mod.push_all(ruck) --вот та функция которая ЗДЕСЬ не работает, но работает в другом месте, не пойму что не так end -- сбросим переменную self.rr_id=nil end --Timer_N_minutes()--пробовал типа по таймеру вызывать, все так-же не работает --<< --*************************************************** -- апдейт погоды дальше все стандартно ... Если сделать так, то рюкзак сбрасывается но походу после my_mod.push_all(ruck) ничего не работает :-( игра не вылетает но повторно скрипт уже не срабатывает как нужно, с таймером пробовал но все так-же.Код таймера не привожу так как там по сути все то-же самое только вызывается с задержкой. Из my_mod.script Функция заимствована из скрипта арены там где телепортирует актера на арену а все вещи складываются в ящик. local function transfer_object_item(item) db.actor:transfer_item(item, in_object) end function push_all(obj) in_object = obj db.actor:inventory_for_each(transfer_object_item) end Эту функцию я тестировал с модовым рюкзаком вызывая ее из калбека когда перс забирает предмет(ы) из ящика и там она работает function actor_binder:take_item_from_box(box, item)-- --my_mod.push_all(obj)--вот так она работает, при перемещении чего либо из ящика срабатывает калбак, инвентарь актора перемещается в ящик, то что мы оттуда забрали перемещается в инвентарь так как и должно по коду игры. --my_mod.Message("take_item_from_box")--типа сообщение для информирования Изменено 23 Августа 2015 пользователем antihumanist Поделиться этим сообщением Ссылка на сообщение
antihumanist 0 Опубликовано 23 Августа 2015 antihumanist, у тебя ruck это серверный объект, а в transfer_item нужно передавать клиентский. Хм а получить его как ? в справочнике из очевидного не нашел Поделиться этим сообщением Ссылка на сообщение
antihumanist 0 Опубликовано 23 Августа 2015 (изменено) Точнее - проверять, пока не появился Ура работает ! спасибо ! --*********************************************************************** --Код тестовый и по хорошему его нужно переделать, но для теста пойдет и так local iTimer --переменная времени для таймера(никто не мешает использовать ее как простой флаг) local obj_ruck-- серверный обдж рюкзака, тут думаю лучше передавать сразу ид, но для теста сойдет function Start_Timer_5_minutes() iTimer = --[[time_global() +]] 300 --тут закоментирован код таймера, просто устанавлевается флаг end function Timer_N_minutes() -- таймер переделанный в функцию проверки на существование, в апдейте if iTimer ~= nil --[[and iTimer < time_global()]] then local c_ruck = level.object_by_id(obj_ruck.id)--поидее если объект не нашелся то его нет(работает) if c_ruck then my_mod.push_all(c_ruck) iTimer = nil--убираем флаг или обнуляем таймер end end end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:update(delta) object_binder.update(self, delta) -- DEBUG slowdown -- slowdown.update() local time = time_global() game_stats.update (delta, self.object) --*************************************************** -->>Treasure rucksack 1/2 if self.rr_id~=nil then--то что мы записали при дропе -- пытаемся получить объект по id local se_obj=alife():object(self.rr_id) -- проверяем, что объекта нет if se_obj==nil or se_obj:section_name()~="inv_ruck" then local ruck=alife():create("active_ruck", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id()) level.map_add_object_spot_ser(ruck.id, "red_location", "%c[255,238,155,23]Моя нычка для хабара") news_manager.send_tip(db.actor, "Тайник заложен.", nil, nil, 5000) obj_ruck = ruck--передаем в переменную Start_Timer_5_minutes()--ставим флаг или таймер --my_mod.push_all(level.object_by_id(ruck.id))--тут работать не будет end -- сбросим переменную self.rr_id=nil end Timer_N_minutes()--выполняем таймер/функцию апдейта состояния рюкзака --<< --*************************************************** -- апдейт погоды Тогда еще пара вопросов уж простите.Делаю фан мод и сборку из чужих скриптов для этого мода и поэтому вопросы совершенно разные. Сделал ремонтные наборы, но столкнулся со странным багом, не совсем понимаю его природу. суть его в том что когда я вызываю подряд две функции на съедание одного и того-же предмета то последняя функция не выполняется и дает глюки, точно так-же с вызовом удаления предмета. Все обернуто в функцию которая вызывается из колбека self.object:set_callback(callback.use_object, self.repair_start, self) function actor_binder:repair_start(obj, who) my_mod.Message("use_object") if obj then main_sleep.sleep(obj) if obj:section() == "repair_kit_outfit" then --здесь указываем предмет, при использовании которого будет срабатывать функция ниже exp_mod.action_repair() --тут функции которые не учавствуют в тесте и уже тестироваись elseif obj:section() == "repair_kit" then exp_mod.repair_all() elseif obj:section() == "repair_kit_wpn" then exp_mod.repair_wpn() --второй вариант ремонта elseif obj:section() == "repair_kit_device" then--вот отсюда вызываю exp_mod.repair_device() elseif obj:section() == "repair_kit_wpn2" then exp_mod.repair_wpn2() elseif obj:section() == "repair_kit_outfit2" then exp_mod.repair_outfit2() end end end --Короче говоря в моде есть три "съедобных" итема ящик с инструментами и ремкомплекты один для брони и другой для оружия, когда игрок пытается съесть ящик с инструментами то выполняется эта функция, которая по задумке должна ремонтировать все во всех слотах при этом съедая/удаляя из инвентаря расходники ремкомплектов. но оставляя инструменты.Не работает когда я пытаюсь вызвать подряд две функции съедания/удаления одного вида предмета.Ремкомплекты так-же обрабатываются при употреблении в пищу, с расчетом одна еденица ремкомплекта на одну еденицу брони/оружия в слоте.С оружием работают последовательно что сделанно для удобства ремонта чего-то одного а не всего сразу. --repair_item_in_slot(num) -- это моя функция ремонта, переделанная, с википедии сталкера, к ней нет нареканий --Она проверяет слот num и возвращает true если предмет был отремонтирован, если в слоте пусто или предмет не того состояния которого требуется для ремонта или еще что не так то возвращает false, так-же информирует игрока. function repair_device()--ящик с инструментами repair_kit_device, функция в которой должно ремонтироваться все что в слотах(сразу) local actor = db.actor local kit_outfit2 = actor:object("repair_kit_outfit2")--ремкомплект для костюма alife():create("repair_kit_device", vector(),0,0,0)--cпавним сразу как съели, хотя работало и если поместить в конец. if kit_outfit2 then--проверяем наличие расходника для ремонта в инвентаре актора --db.actor:eat(db.actor:object("repair_kit_outfit2")) --можно его сразу тупо съесть if repair_item_in_slot(6) then --тогда этот код здесь не нужен, он запустися в биндере при "поедании" "repair_kit_outfit2" alife():release(alife():object(kit_outfit2:id()), true)--и этот код будет то-же не нужен end-- end--конец ремонта костюма local kit_wpn2 = actor:object("repair_kit_wpn2")--ремкомплект для оружия, поидее тут я хочу отремонтировать сразу все стволы, т.е. два слота 1 и 2 поэтому делаю два раза одно и то-же. if kit_wpn2 then --db.actor:eat(db.actor:object("repair_kit_wpn2"))можно место удаления съедать, но у меня так не работало для двух одинаковых предметов сразу и я решил переделать if repair_item_in_slot(2) then alife():release(alife():object(kit_wpn2:id()), true) end end --Если раскомментировать код ниже, то он работать не будет ! но почему ? --kit_wpn2 = actor:object("repair_kit_wpn2")--Здесь еще раз инициализируется на случай если объект съеден/удален кодом выше --if kit_wpn2 then ----db.actor:eat(db.actor:object("repair_kit_wpn2"))--либо код жрачки либо код удаления --if repair_item_in_slot(1) then--при юзе кода жрачки не требуется --alife():release(alife():object(kit_wpn2:id()), true) --end --end end Изменено 24 Августа 2015 пользователем Kirgudu Поделиться этим сообщением Ссылка на сообщение
antihumanist 0 Опубликовано 24 Августа 2015 Ужасно. Неизвестно что делается неизвестно когда с неизвестно чем.Вот переделал все для демонстрации бага на стандартных вещах и без "лишних" функций.Вызов бага показан в функции test_bug.Остальное привел для полноты данных. --Добавление нового колбека в bind_stalker.script function actor_binder:reinit() object_binder.reinit(self) local npc_id = self.object:id() db.storage[npc_id] = { } self.st = db.storage[npc_id] self.st.pstor = nil self.next_restrictors_update_time = -10000 self.object:set_callback(callback.inventory_info, self.info_callback, self) self.object:set_callback(callback.article_info, self.article_callback, self) self.object:set_callback(callback.on_item_take, self.on_item_take, self) self.object:set_callback(callback.on_item_drop, self.on_item_drop, self) self.object:set_callback(callback.trade_sell_buy_item, self.on_trade, self) -- for game stats --self.object:set_callback(callback.actor_sleep, self.sleep_callback, self) self.object:set_callback(callback.task_state, self.task_callback, self) --self.object:set_callback(callback.map_location_added, self.map_location_added_callback, self) self.object:set_callback(callback.level_border_enter, self.level_border_enter, self) self.object:set_callback(callback.level_border_exit, self.level_border_exit, self) self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self) --******************************РЕМОНТ***************************************************** self.object:set_callback(callback.use_object, self.repair_start, self)--Установка коллбэка --***************************************************************************************** end --******************************РЕМОНТ***************************************************** function actor_binder:repair_start(obj, who)--Функция коллбека callback.use_object if obj then if obj:section() == "bread" then exp_mod.test_debug() end end end --***************************************************************************************** function actor_binder:net_destroy() if(actor_stats.remove_from_ranking~=nil)then actor_stats.remove_from_ranking(self.object:id()) end -- game_stats.shutdown () db.del_actor(self.object) sr_light.clean_up () self.object:set_callback(callback.inventory_info, nil) self.object:set_callback(callback.article_info, nil) self.object:set_callback(callback.on_item_take, nil) self.object:set_callback(callback.on_item_drop, nil) --self.object:set_callback(callback.actor_sleep, nil) self.object:set_callback(callback.task_state, nil) self.object:set_callback(callback.level_border_enter, nil) self.object:set_callback(callback.level_border_exit, nil) self.object:set_callback(callback.take_item_from_box, nil) --****************************РЕМОНТ********************************** self.object:set_callback(callback.use_object, nil)-- --******************************************************************** if sr_psy_antenna.psy_antenna then sr_psy_antenna.psy_antenna:destroy() sr_psy_antenna.psy_antenna = false end xr_sound.stop_all_sound_object() object_binder.net_destroy(self) end --exp_mod.script--Мой скрипт --Тестовая функция function test_debug()--При использовании "bread" alife():create("bread", vector(),0,0,0) local actor = db.actor local test_obj = actor:object("conserva") --При использовании "bread" нужно удалить два test_obj (если их имеется столько в инвентаре). if test_obj then alife():release(alife():object(test_obj:id()), true) end test_obj = actor:object("conserva") if test_obj then alife():release(alife():object(test_obj:id()), true)--этот код не срабатывает но из игры не выкидывает end end --При вызове этой функции срабатывает только удаление первого test_obj, кроме того повторно эта функция уже не работает. Поделиться этим сообщением Ссылка на сообщение