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 Ссылка на комментарий
Colder 12 Опубликовано 26 Октября 2021 Поделиться Опубликовано 26 Октября 2021 Подскажите в чем проблема. Пытаюсь вывести прогресс бар для каждого слота но не могу выровнить шкалу. Пишу так: Скрытый текст local slots = { [1] = {100, 190}, [2] = {330, 190}, [4] = {330, 440}, [6] = {170, 400}, } for num, xy in pairs(slots) do local item = db.actor:item_in_slot(num) if item then local item_sect = item:section() local x, y, width, height, y_fix, x_fix, w_fix = axr_base.icon_new_pos(item_sect, num) --// окно local weapon_tex = CUIStatic() self:AttachChild(weapon_tex) local wnd_x, wnd_y = unpack(xy) weapon_tex:Init(wnd_x + x_fix, wnd_y + y_fix, w_fix * f_size, height * f_size) --// текстура weapon_tex:InitTexture("ui\\ui_icon_equipment") weapon_tex:SetStretchTexture(true) weapon_tex:SetOriginalRect(x, y, width, height) --// прогресс local wpn_condition_progress = 0 local bar = xml:InitProgressBar("bar_frame", weapon_tex) wpn_condition_progress = item:condition()*100 bar:SetProgressPos(wpn_condition_progress) -- имя local wnd_name = "repair_wpn_" .. num self:Register(xml:Init3tButton(wnd_name, self), wnd_name) self:AddCallback("repair_wpn_" ..num, ui_events.BUTTON_CLICKED, function() self:repair_wpn(num) end, self) Скрытый текст <bar_frame_ x="50" y="50" width="56" height="5" horz="1" min="0" max="100" pos="1"> <background> <texture>ui_cop_Game_progress_efficiency_full</texture> </background> <min_color r="86" g="196" b="209"/> <middle_color r="86" g="196" b="209"/> <max_color r="86" g="196" b="209"/> <progress> <texture>ui_cop_item_cond</texture> </progress> </bar_frame> Итог: https://yadi.sk/i/AH1ZOpH45nyQXQ Ссылка на комментарий
Chypakabra 597 Опубликовано 26 Октября 2021 Поделиться Опубликовано 26 Октября 2021 @Colder Привет мне кажется что всё дело вот в чём: ты задаёшь координаты слотов 9 часов назад, Colder сказал: local slots = { [1] = {100, 190}, [2] = {330, 190}, [4] = {330, 440}, [6] = {170, 400}, } а уже к ним привязываешь координаты прогресса 9 часов назад, Colder сказал: <bar_frame_ x="50" y="50" соответственно получается где-то так 9 часов назад, Colder сказал: local slots = { [1] = {100 + 50, 190 + 50}, [2] = {330 + 50, 190 + 50}, [4] = {330 + 50, 440 + 50}, [6] = {170 + 50, 400 + 50}, } 1 Личный АРХИВ по S.T.A.L.K.E.R Архив по Legends of the Zone Trilogy Ссылка на комментарий
Colder 12 Опубликовано 27 Октября 2021 Поделиться Опубликовано 27 Октября 2021 Не помогло Ссылка на комментарий
naxac 2 537 Опубликовано 27 Октября 2021 Поделиться Опубликовано 27 Октября 2021 (изменено) @Colder , ну всё правильно выводится: на 50 пикселей правее левого края и на 50 ниже верхнего. А ты как задумывал? То есть, где надо, чтобы была шкала? Изменено 27 Октября 2021 пользователем naxac Аддон для ОП-2.09.2: Яндекс/Google/GitHub Ссылка на комментарий
Colder 12 Опубликовано 27 Октября 2021 Поделиться Опубликовано 27 Октября 2021 (изменено) @naxac Мне нужно выровнить шкалу! А не иконку. Изменено 27 Октября 2021 пользователем Colder Ссылка на комментарий
Chypakabra 597 Опубликовано 27 Октября 2021 Поделиться Опубликовано 27 Октября 2021 3 часа назад, Colder сказал: Не помогло Что именно не помогло? я же сказал, что координаты прогресса у тебя жостко привязаны к координатам иконки, и выводятся на 50 пихелей правее и 50 ниже - от левого верхнего угла иконки, а так как иконки имеют разные размеры - нужно это учитывать! либо сдвигать прогресс на дополнительное количество пихелей - относительно иконки - для каждой иконки, либо выводить прогресс по своим собственным координатам - не привязанных к иконке, 1 1 Личный АРХИВ по S.T.A.L.K.E.R Архив по Legends of the Zone Trilogy Ссылка на комментарий
Colder 12 Опубликовано 27 Октября 2021 Поделиться Опубликовано 27 Октября 2021 Вот я и не могу сдвинуть сам прогресс Ссылка на комментарий
Chypakabra 597 Опубликовано 27 Октября 2021 Поделиться Опубликовано 27 Октября 2021 3 часа назад, Colder сказал: Вот я и не могу Простейший вариант - чтоб не плодить костыли и не писать кучу проверок и функций Скрытый текст <bar_frame_1 x="50" y="50" width="56" height="5" horz="1" min="0" max="100" pos="1"> <background> <texture>ui_cop_Game_progress_efficiency_full</texture> </background> <min_color r="86" g="196" b="209"/> <middle_color r="86" g="196" b="209"/> <max_color r="86" g="196" b="209"/> <progress> <texture>ui_cop_item_cond</texture> </progress> </bar_frame_1> <bar_frame_2 x="50" y="50" width="56" height="5" horz="1" min="0" max="100" pos="1"> <background> <texture>ui_cop_Game_progress_efficiency_full</texture> </background> <min_color r="86" g="196" b="209"/> <middle_color r="86" g="196" b="209"/> <max_color r="86" g="196" b="209"/> <progress> <texture>ui_cop_item_cond</texture> </progress> </bar_frame_2> <bar_frame_4 x="50" y="50" width="56" height="5" horz="1" min="0" max="100" pos="1"> <background> <texture>ui_cop_Game_progress_efficiency_full</texture> </background> <min_color r="86" g="196" b="209"/> <middle_color r="86" g="196" b="209"/> <max_color r="86" g="196" b="209"/> <progress> <texture>ui_cop_item_cond</texture> </progress> </bar_frame_4> <bar_frame_6 x="50" y="50" width="56" height="5" horz="1" min="0" max="100" pos="1"> <background> <texture>ui_cop_Game_progress_efficiency_full</texture> </background> <min_color r="86" g="196" b="209"/> <middle_color r="86" g="196" b="209"/> <max_color r="86" g="196" b="209"/> <progress> <texture>ui_cop_item_cond</texture> </progress> </bar_frame_6> делаем 4 прогресса - так можно двигать их независимо а чтоб это заработало Скрытый текст --// прогресс local wpn_condition_progress = 0 local bar = xml:InitProgressBar("bar_frame_"..num, weapon_tex) ---- измени эту строку вот так wpn_condition_progress = item:condition()*100 bar:SetProgressPos(wpn_condition_progress) 100% уверенности в работоспособности нет - так как не могу проверить но вроде должно работать 1 1 Личный АРХИВ по S.T.A.L.K.E.R Архив по Legends of the Zone Trilogy Ссылка на комментарий
mole venomous 3 635 Опубликовано 28 Октября 2021 Поделиться Опубликовано 28 Октября 2021 (изменено) Всем привет. Ознакомился с возможностями движка ОГСР, но видимо недостаточно хорошо. Есть ли на этом движке возможность определить предмет на поясе и далее производить с ним какие-либо действия? Т.е. речь не о проверке local item = inventory.belt["item"] а именно о том, что бы заданный объект можно было хитануть, удалить и т.п. Изменено 28 Октября 2021 пользователем mole venomous Здесь могла быть ваша реклама. Ссылка на комментарий
naxac 2 537 Опубликовано 28 Октября 2021 Поделиться Опубликовано 28 Октября 2021 (изменено) @mole venomous , можно сделать так: local obj = db.actor:object("item") if obj and db.actor:is_on_belt(obj) then -- хитануть, удалить и т.п. end Или так (это подойдёт, если у актера может быть несколько предметов с секцией "item"): local obj for i = 0, db.actor:belt_count()-1 do obj = db.actor:item_on_belt(i) if obj and obj:section() == "item" then -- хитануть, удалить и т.п. end end Изменено 28 Октября 2021 пользователем naxac 1 2 Аддон для ОП-2.09.2: Яндекс/Google/GitHub Ссылка на комментарий
bastor 133 Опубликовано 29 Октября 2021 Поделиться Опубликовано 29 Октября 2021 Всем привет! Помогите разобраться. Хочу поместить в динамический худ мод NLC статик показателей ГГ . При вызове худа cтатик создается все работает но вот при закрытии удалить его ни как не получается. На get_hud():RemoveCustomStatic ни как не реагирует. Скрытый текст local function getSt(text, alpha, red, green, blue) alpha = (alpha<0 and 0) or (alpha>10 and 10) or alpha local param = 10 - math.floor(alpha + 0.5) text = string.sub(text, 1) .. string.format("%1.0f%%", alpha*10) alpha = 250 - param*10 return {text, alpha, red, green, blue} end local function show() local hud = get_hud() local custom_static local tbl = { ["actor_health"] = getSt("Здоровье:", db.actor.health *10, 0, 255, 0), ["actor_psy_health"] =getSt("Психика:", db.actor.psy_health *10, 0, 250, 255), ["actor_satiety"] = getSt("Голод:", 10 - db.actor.satiety *10, 255, 155, 0), ["actor_radiation"] = getSt("Облучение:", db.actor.radiation *10, 255, 255, 0), ["actor_sleep"] = getSt("Усталость:", nlc_vars.gg_need_sleep /25, 255, 255, 255),} for k,v in pairs(tbl) do custom_static = hud:GetCustomStatic(k) if custom_static == nil then hud:AddCustomStatic(k, true) elseif v then custom_static:wnd():SetText(v[1]) custom_static:wnd():SetTextColor(v[2],v[3],v[4],v[5]) end end end Ссылка на комментарий
Black_Raven_03 37 Опубликовано 31 Октября 2021 Поделиться Опубликовано 31 Октября 2021 (изменено) @bastor, из очевидного: не вижу кода удаления статика, только добавления (я ж не телепат и не "крутой хацкер"!); также, если у тебя GetCustomStatic(k), то и RemoveCustomStatic должен иметь параметр-указатель кого-что удалять (не всё же подряд и не случайный!) Изменено 31 Октября 2021 пользователем Black_Raven_03 Скрытый текст AMD Ryzen 5 3600, 32GB DDR4-3200, AFOX GeForce GTX1050Ti и нормально сталкерим в НА5.1, НА7, OGSE-0693, OGSR, НС2016, OLR, OFFLIFE, CoC, LADC, CoP Gunslinger, CoP GM Gunslinger, ShoC GA, Legend Return, Anomaly, CS OGSM! Мозг состоит на 80 процентов из жидкости, и мало того, что она тормозная, так многим еще конкретно не долили...@Denikius136 Ссылка на комментарий
bastor 133 Опубликовано 31 Октября 2021 Поделиться Опубликовано 31 Октября 2021 1 час назад, Black_Raven_03 сказал: должен иметь параметр-указатель кого-что удалять Разобрался уже статик не удалялся потому что выполнялся внутри функции худа вынес его в отдельный скрипт и все заработало. 1 1 Ссылка на комментарий
Это популярное сообщение. Капрал Хикс 558 Опубликовано 31 Октября 2021 Это популярное сообщение. Поделиться Опубликовано 31 Октября 2021 В общем, домучил я скрипт боевой схемы БТРа от Мишаня_Лютый aka CRAZY_STALKER666 + правки Graff46, чтобы машины корректно ехали к 1-й точке пути и при запрокидывании набок пытались восстановиться. Скрытый текст ----------------------------------------------------------------------------------------------------------------------- -- Physic vehicle control ----------------------------------------------------------------------------------------------------------------------- -- Исходный скрипт: Evgeniy Negrobov (Jon) jon@gsc-game.kiev.ua -- Перевод на xr_logic: Andrey Fidrya (Zmey) af@svitonline.com -- Доработка для БТР: Oleg Kreptul (Haron) haronk@ukr.net -- Доработки чтобы машины корректно ехали к 1-й точке пути и при запрокидывании набок пытались восстановиться: Graff46 -- Обновлённая боевая схема БТР - Мишаня_Лютый aka CRAZY_STALKER666. Old Episodes - Epilogue -- ВНИМАНИЕ! Для монстров и сталкеров используются db.monster_stock и db.creature соответственно -- Второе при желании можно перевести и на перебор цифрами, ничего не поменяется, но лагов будет больше ----------------------------------------------------------------------------------------------------------------------- function printf() end local pi_2 = math.pi / 3 -- 60 degree local def_min_delta_per_sec = 0.02 local def_min_car_explode_time = 1000 local def_moving_speed = 10 --local def_arriving_factor = 0.4 local def_arriving_dist = 1.0 local def_not_rotating_angle = 0.4 local def_min_fire_time = 0 local def_update_time = 1.6 local def_fire_range = 50 local def_max_fc_upd_num = 1000 -- default maximum fastcall updates num local def_arriving_koef = 3 --70 local delay_after_ignition = 500 local state_none = 0 local state_moving_fwd = 1 local state_moving_rot_left = 2 local state_moving_rot_right = 3 local state_moving_stop = 4 local state_moving_end = 5 local state_cannon_rotate = 1 local state_cannon_follow = 2 local state_cannon_delay = 3 local state_cannon_stop = 4 local state_shooting_on = 1 local state_firetarget_points = 1 local state_firetarget_enemy = 2 class "action_car" function action_car:__init(obj, storage) self.object = obj self.car = self.object:get_car() self.st = storage --вставка1 self.friends = {} end function action_car:reset_scheme(loading) self.destroyed = false self.object:set_nonscript_usable(false) self.object:set_tip_text("") self.show_tips = self.st.show_tips self.tip_use = self.st.tip_use self.tip_locked = self.st.tip_locked if self.st.invulnerable then self.def_health = self.object.health end self.headlights = object.deactivate if self.st.headlights == "on" then self.headlights = object.activate end xr_logic.mob_capture(self.object, true) action(self.object, object("left_light", self.headlights), cond(cond.time_end, time_infinite)) xr_logic.mob_capture(self.object, true) action(self.object, object("right_light", self.headlights), cond(cond.time_end, time_infinite)) self.usable = self.st.usable --if self.usable ~= nil then -- self.car_holder = self.object.get_current_holder() --engaged() --else if self.usable == nil then self.car:SetExplodeTime(0) -- (-1) if self.car:HasWeapon() then self.car:Action(CCar.eWpnActivate,1) self.hasWeapon = true else self.hasWeapon = false end if loading then self.speed = xr_logic.pstor_retrieve(self.object, "speed") self.loop = xr_logic.pstor_retrieve(self.object, "loop") self.min_delta_per_sec = xr_logic.pstor_retrieve(self.object, "min_delta_per_sec") self.min_car_explode_time = xr_logic.pstor_retrieve(self.object, "min_car_explode_time") self.state_moving = xr_logic.pstor_retrieve(self.object, "state_moving") else self.speed = def_moving_speed self.loop = false self.min_delta_per_sec = def_min_delta_per_sec self.min_car_explode_time = def_min_car_explode_time self.state_moving = state_none end --xr_logic.mob_capture(self.object, true) self.st.signals = {} self.fc_upd_num = 0 -- fastcall updates num self.fc_upd_avg = 10 -- average time of the fastcall updates (in millisecond) self.fc_last_upd_tm = -1 -- fastcall last update time self.last_pos = nil self.last_pos_time = 0 self.state_delaying = false --self.state_moving = state_none self.target_walk_pt = -2 -- path_walk if self.st.path_walk then self.path_walk = patrol(self.st.path_walk) if not self.path_walk then abort("object '%s': unable to find path_walk '%s' on the map", self.object:name(), self.st.path_walk) end self:start_car() self.path_walk_count = self.path_walk:count() self.target_walk_pt = 0--self:get_nearest_walkpoint() --= -1 --if not self.path_walk_info then self.path_walk_info = utils.path_parse_waypoints(self.st.path_walk) if not self.path_walk_info then abort("object '%s': path_walk ('%s'): unable to obtain path_walk_info from path", self.object:name(), self.st.path_walk) end --end self.arrival_signalled = false self.target_dist = -1 if loading then self.target_walk_pt = xr_logic.pstor_retrieve(self.object, "target_walk_pt") if self.target_walk_pt == -1 then self.target_walk_pt = self:get_nearest_walkpoint() end else self.target_walk_pt = self:get_nearest_walkpoint() end if self:at_target_walkpoint() then self:walk_arrival_callback(self.target_walk_pt) end self:go_to_walkpoint(self.target_walk_pt) else self.target_walk_pt = -2 self.state_moving = state_moving_stop end self.state_firetarget = state_none self.state_cannon = state_none self.state_shooting = state_none self.target_fire_pt = nil self.target_fire_pt_idx = 0 self.target_obj = nil self.on_target_vis = nil self.on_target_nvis = nil if self.hasWeapon then --if loading then --self.state_cannon = xr_logic.pstor_retrieve(self.object, "state_cannon") --self.state_shooting = xr_logic.pstor_retrieve(self.object, "state_shooting") --end self:set_shooting(self.state_shooting) local n = 0 if self.st.fire_target == "points" then self.state_firetarget = state_firetarget_points else if self.st.fire_target == "actor" and db.actor:alive() then self.target_obj = db.actor self.state_firetarget = state_firetarget_enemy else n = tonumber(self.st.fire_target) if n then obj = level_object_by_sid(n) if obj and obj:alive() then self.target_obj = obj self.state_firetarget = state_firetarget_enemy end end end --if self.target_obj then -- self.target_ph_shell = self.target_obj:get_physics_shell() --end end self.fire_track_target = self.st.fire_track_target if self.st.on_target_vis then vis = self.st.on_target_vis if vis.v1 == "actor" then vis.v1 = db.actor self.on_target_vis = vis else n = tonumber(vis.v1) if n then obj = level_object_by_sid(n) if obj and obj:alive() then vis.v1 = obj self.on_target_vis = vis end end end end if self.st.on_target_nvis then nvis = self.st.on_target_nvis if nvis.v1 == "actor" then nvis.v1 = db.actor self.on_target_nvis = nvis else n = tonumber(nvis.v1) if n then obj = level_object_by_sid(n) if obj and obj:alive() then nvis.v1 = obj self.on_target_nvis = nvis end end end end self.path_fire = nil self.path_fire_info = nil self.fire_pt_count = 0 self.def_fire_time = self.st.fire_time if self.st.fire_rep then if self.st.fire_rep == "inf" then self.def_fire_rep = -1 else local c = tonumber(self.st.fire_rep) self.def_fire_rep = if_then_else(c > 0, c, 0) end else self.def_fire_rep = 0 end self.fire_rep = self.def_fire_rep self.fire_range_sqr = self.st.fire_range * self.st.fire_range -- path_fire if self.state_firetarget == state_firetarget_points and self.st.path_fire then self.path_fire = patrol(self.st.path_fire) if not self.path_fire then abort("object '%s': unable to find path_fire '%s' on the map", self.object:name(), self.st.path_fire) end if not self.path_fire_info then self.path_fire_info = utils.path_parse_waypoints(self.st.path_fire) if not self.path_fire_info then abort("object '%s': path_fire ('%s'): unable to obtain path_fire_info from path", self.object:name(), self.st.path_fire) end end -- точки прострела для первой точки движения self:change_fire_pts() if self.st.auto_fire then self.car:Action(CCar.eWpnAutoFire, 1) else self.car:Action(CCar.eWpnAutoFire, 0) end self:fire_arrival_callback(self.target_fire_pt_idx) --self:rot_to_firepoint(self.target_fire_pt) --self:set_shooting(self.state_shooting) elseif self.state_firetarget == state_firetarget_enemy then self.state_shooting = state_none self.state_cannon = state_cannon_follow --self.target_fire_pt = db.actor:position() --self:rot_to_firepoint(self.target_fire_pt) else self.state_firetarget = state_none self.state_cannon = state_none self.state_shooting = state_none end --self:set_shooting(self.state_shooting) end --if self.st.path_walk then -- if self:at_target_walkpoint() and self.state_firetarget == state_none then -- self:walk_arrival_callback(self.target_walk_pt) -- end -- -- self:go_to_walkpoint(self.target_walk_pt) --end --printf("car <move>: start target_pt2 = %d", self.target_walk_pt) end self.object:set_fastcall(self.fastcall, self) end function action_car:save() if self.usable == nil then xr_logic.pstor_store(self.object, "speed", self.speed) xr_logic.pstor_store(self.object, "loop", self.loop) xr_logic.pstor_store(self.object, "min_delta_per_sec", self.min_delta_per_sec) xr_logic.pstor_store(self.object, "min_car_explode_time", self.min_car_explode_time) xr_logic.pstor_store(self.object, "state_moving", self.state_moving) xr_logic.pstor_store(self.object, "target_walk_pt", self.target_walk_pt) -- or -2) end end function action_car:get_nearest_walkpoint() return utils.get_nearest_waypoint(self.object, self.st.path_walk, self.path_walk, self.path_walk_count) end function action_car:get_next_walkpoint() if self.target_walk_pt >= 0 and self.target_walk_pt < self.path_walk_count - 1 then --printf("car <move>: action_car:get_next_walkpoint(%d)", self.target_walk_pt + 1) return self.target_walk_pt + 1 elseif self.target_walk_pt == -1 or self.loop then --printf("car <move>: action_car:get_next_walkpoint(0)") return 0 end --printf("car <move>: action_car:get_next_walkpoint(-2)") return -2 end function action_car:at_target_walkpoint() if self.target_walk_pt == -2 then return true end local curVel = self.car:CurrentVel():magnitude() local dist = self.object:position():distance_to(self.path_walk:point(self.target_walk_pt)) --local arrived = 2 * dist < def_update_time * (curVel.x + self.speed) --def_update_time > 2 * dist / (curVel.x + self.speed) --local arrived = dist < curVel.x * def_arriving_factor --8 -- def_arriving_koef * self.fc_upd_avg / 1000 > 2 * dist / (curVel.x + self.speed) local arrived = false --2000 * dist < def_arriving_koef * self.fc_upd_avg * (curVel + self.speed) if self.fc_upd_avg < 100 then arrived = 2000 * dist < def_arriving_koef * self.fc_upd_avg * (curVel + self.speed) --printf("car <move>: check formula (%f < %f)", 2000 * dist, def_arriving_koef * self.fc_upd_avg * (curVel + self.speed)) if arrived then --printf("car <move>: at target pt by formula.") end end if not arrived then local diff_angle = angle_xz(self.object, self.path_walk:point(self.target_walk_pt)) --printf("car <move>: dist(%f), angle(%f).", dist, diff_angle) arrived = dist < 2 or diff_angle >= math.pi if arrived then --printf("car <move>: at target pt by dist(%f) and angle(%f).", dist, diff_angle) --printf("car <move>: at target pt by dist and angle.") end end local diff = dist - self.target_dist --printf("car <move>: dist = %f, target = %f, diff = %f, curVel = %f, speed = %f", dist, self.target_dist, diff, curVel, self.speed) if self.target_dist ~= -1 and not arrived then if diff > 0 then if diff > def_arriving_dist then arrived = true --printf("car <move>: at target pt by diff(%f).", diff) end else self.target_dist = dist end else self.target_dist = dist end --[[ --printf("car <move>: action_car:at_target_walkpoint(self.target_walk_pt=%d) = %d (arrived = %s)", self.target_walk_pt, dist, utils.to_str(arrived)) --if arrived then --printf("car <move>: arrived = %f > %f, dist(%f), diff(%f), curSpd(%f), spd(%f)", --def_arriving_koef * self.fc_upd_avg / 1000, --2 * dist / (curVel.x + self.speed), def_arriving_koef * self.fc_upd_avg * (curVel + self.speed), 2000 * dist, dist, diff, curVel, self.speed) --printf("car <move>: arrived = %f < (%f,%f,%f) * %f, spd(%f)", dist, curVel.x, curVel.y, curVel.z, def_arriving_factor, self.speed) --end --]] if arrived then self.target_dist = -1 end return arrived end function action_car:go_to_walkpoint(pt) --action(self.object, object("left_light", object.activate), cond(cond.time_end, 1000)) --action(self.object, object("right_light", object.activate), cond(cond.time_end, 1000)) if self.state_delaying then if time_global() - self.delay_time_start >= delay_after_ignition then --printf("car <state>: stop delaying after ignition") self.state_delaying = false else --printf("car <state>: delaying after ignition") self.state_moving = state_moving_stop return end end if pt == nil or pt < 0 then if self.state_cannon ~= state_cannon_stop then self:stop_car() self.state_moving = state_moving_end end --printf("car <state>: pt < 0 or pt == nil") return end local diff_angle = angle_xz(self.object, self.path_walk:point(pt)) local accel = move.none local curVel = self.car:CurrentVel():magnitude() --printf("car <move>: curVel = %f, speed = %f", curVel, self.speed) if curVel < self.speed then accel = move.fwd --printf("car <move>: forward") elseif curVel > self.speed * 1.15 or diff_angle >= math.pi then accel = move.back --printf("car <move>: backward") end --printf("car <move>: diff_angle = %f, katet = %f", diff_angle, get_katet(self.object, self.path_walk:point(pt))) --if utils.no_need_to_rotate_xz(self.object, self.path_walk:point(pt)) then if diff_angle < def_not_rotating_angle then if self.state_moving ~= state_moving_fwd and accel ~= move.none then --printf("car <move>: no_need_to_rotate. speed = %f, time = %f", self.speed, self.fc_upd_avg) xr_logic.mob_capture(self.object, true) action(self.object, move(accel, self.speed), --move.on + --object("right_light", self.headlights), --object("left_light", self.headlights), cond(cond.time_end, time_infinite)) --self.fc_upd_avg)) self.state_moving = state_moving_fwd end else -- Поворачиваться нужно, но в какую сторону? local rotate_left = utils.angle_left_xz(self.object:direction(), utils.vector_copy_by_val(self.path_walk:point(pt) ):sub(self.object:position())) --printf("car <move>: must rotate: left? %s. speed = %f, time = %f", utils.to_str(rotate_left), self.speed, self.fc_upd_avg) if rotate_left then if self.state_moving ~= state_moving_rot_left then xr_logic.mob_capture(self.object, true) action(self.object, move(accel + move.left, self.speed), --move.on + --object("right_light", self.headlights), --object("left_light", self.headlights), cond(cond.time_end, time_infinite)) --self.fc_upd_avg)) self.state_moving = state_moving_rot_left end else if self.state_moving ~= state_moving_rot_right then xr_logic.mob_capture(self.object, true) action(self.object, move(accel + move.right, self.speed), --move.on + --object("right_light", self.headlights), --object("left_light", self.headlights), cond(cond.time_end, time_infinite)) --self.fc_upd_avg)) self.state_moving = state_moving_rot_right end end end end function action_car:start_car() xr_logic.mob_capture(self.object, true) action(self.object, move(move.on --+ move.fwd , 100), cond(cond.time_end, 5000)) --self.speed = 0 self.state_delaying = true self.delay_time_start = time_global() end function action_car:stop_car() self.state_delaying = false self.speed = 0 xr_logic.mob_capture(self.object, true) action(self.object, move(move.off + move.handbrake, 0), cond(cond.time_end, 3000)) --cond(cond.move_end)) --self.target_walk_pt = -1 end function action_car:walk_arrival_callback(index) if index == -2 then return end local suggested_explode = self.path_walk_info[index]["explode"] if suggested_explode == "true" then --self:car_explode() self.object.health = 0 self.car:Action(CCar.eWpnActivate, 0) end local suggested_spd = self.path_walk_info[index]["spd"] if suggested_spd then self.speed = tonumber(suggested_spd) else self.speed = def_moving_speed end local suggested_loop = self.path_walk_info[index]["loop"] if suggested_loop == "true" then self.loop = true else self.loop = false end local suggested_dps = self.path_walk_info[index]["dps"] if suggested_dps then self.min_delta_per_sec = tonumber(suggested_dps) else self.min_delta_per_sec = def_min_delta_per_sec end local suggested_exptm = self.path_walk_info[index]["exptm"] if suggested_exptm then self.min_car_explode_time = tonumber(suggested_exptm) else self.min_car_explode_time = def_min_car_explode_time end local sig = self.path_walk_info[index]["sig"] if sig then --self.st.signals[sig] = true self:set_signal(sig) end if self.hasWeapon and self.state_firetarget == state_firetarget_points then local next_idx = self:get_next_walkpoint() --local next_idx = self.target_walk_pt if next_idx >= 0 then local fw = self.path_walk_info[next_idx]["fw"] if fw then self.fire_wait = if_then_else(fw == "true", true, false) else self.fire_wait = false end local fr = self.path_walk_info[next_idx]["fr"] if fr then if fr == "inf" then self.fire_rep = -1 else local c = tonumber(fr) self.fire_rep = if_then_else(c > 0, c, 0) end else self.fire_rep = self.def_fire_rep end else self.fire_wait = false self.fire_rep = self.def_fire_rep end end -- Выбрать следующую точку езды: self.target_walk_pt = self:get_next_walkpoint() --if not self.target_walk_pt then -- self:stop_car() -- Остановить машину --if self.state_cannon == state_cannon_stop then -- xr_logic.mob_capture(self.object, true) --end --action(self.object, move(move.off, 0), cond(cond.time_end, 1000)) --self.state_moving = state_moving_end -- return --end if self.target_walk_pt >= 0 then -- Если эта точка рядом и уже приехали - не ждать апдейта, чтобы вызвать callback if self:at_target_walkpoint() then self:walk_arrival_callback(self.target_walk_pt) else --self.target_dist = -1 self:go_to_walkpoint(self.target_walk_pt) end else self.target_walk_pt = -2 if self.state_moving ~= state_moving_stop and self.state_moving ~= state_moving_end then self:stop_car() self.state_moving = state_moving_end end end end function action_car:change_fire_pts() self.state_cannon = state_none self.state_shooting = state_none self.fire_pt_arr = {} self.fire_pt_count = 0 self.target_fire_pt_idx = 0 self.target_fire_pt = nil self.fire_rot_dir = 1 self.fire_start_time = 0 if not self.path_fire then return end local fire_idx if self.target_walk_pt >= 0 then -- Значение флагов огневых точек, котые будем искать: local fire_flags = self.path_walk_info[self.target_walk_pt].flags if fire_flags:get() == 0 then return end local this_val for fire_idx = 0, self.path_fire:count() - 1 do this_val = self.path_fire_info[fire_idx].flags if this_val:equal(fire_flags) then table.insert(self.fire_pt_arr, fire_idx) self.fire_pt_count = self.fire_pt_count + 1 end end else for fire_idx = 0, self.path_fire:count() - 1 do table.insert(self.fire_pt_arr, fire_idx) end self.fire_pt_count = self.path_fire:count() end print_table(self.fire_pt_arr) if self.fire_pt_count == 0 then self.state_cannon = state_cannon_stop return end --if self.fire_pt_count > 0 then -- self.target_fire_pt_idx = 0 -- self.target_fire_pt = self.path_fire:point(self.fire_pt_arr[0]) --end end function action_car:get_next_firepoint() if self.fire_pt_count < 1 then return nil end local pt_idx if self.target_fire_pt_idx > 0 then -- not first time if self.fire_pt_count > 1 then -- we have at least 2 point to switch pt_idx = self.target_fire_pt_idx + self.fire_rot_dir if (pt_idx < 1 or pt_idx > self.fire_pt_count) then self.fire_rot_dir = -self.fire_rot_dir -- change rotate direction [-1,1] --printf("car <fire>: changing direction") if self.fire_rep == -1 then pt_idx = self.target_fire_pt_idx + self.fire_rot_dir elseif self.fire_rep > 0 then pt_idx = self.target_fire_pt_idx + self.fire_rot_dir self.fire_rep = self.fire_rep - 1 else pt_idx = 0 end end elseif self.fire_rep == -1 then -- left same point in the infinity loop pt_idx = 1 elseif self.fire_rep > 0 then -- left same point if loop defined pt_idx = 1 self.fire_rep = self.fire_rep - 1 end else pt_idx = 1 end --self.target_fire_pt_idx = pt_idx if pt_idx > 0 then return pt_idx, self.path_fire:point(self.fire_pt_arr[pt_idx]) end self.state_firetarget = state_none return pt_idx, nil end function action_car:rot_to_firepoint(pt) --[[ if pt then self.car:SetParam(CCar.eWpnDesiredPos, pt) end --printf("car <fire>: action_car:rot_to_firepoint(%d)", shooting) self.car:Action(CCar.eWpnFire, shooting) --]] if self.target_fire_pt then -- self.state_cannon = state_cannon_rotate self.car:SetParam(CCar.eWpnDesiredPos, self.target_fire_pt) --printf("car <fire>: action_car:rot_to_firepoint(%d)", self.target_fire_pt_idx) --else -- self.state_cannon = state_cannon_stop end end function action_car:set_shooting(shooting) self.car:Action(CCar.eWpnFire, shooting) end function action_car:fire_arrival_callback(cur_index) if self.fire_pt_count < 1 or self.state_cannon == state_cannon_stop then return end if self.state_cannon == state_cannon_delay then -- Выбрать следующую точку езды: self.target_fire_pt_idx, self.target_fire_pt = self:get_next_firepoint() if self.target_fire_pt then self.state_cannon = state_cannon_rotate if self.fire_rot_dir == 1 and self.fire_forward or self.fire_rot_dir == -1 and self.fire_backward then self.state_shooting = state_shooting_on else self.state_shooting = state_none end self:rot_to_firepoint(self.target_fire_pt) self:set_shooting(self.state_shooting) else self.state_cannon = state_cannon_stop if self.state_shooting ~= state_none then self.state_shooting = state_none self:set_shooting(self.state_shooting) self:set_signal("fire_end") end end return end if cur_index > 0 then local idx = self.fire_pt_arr[cur_index] local ff = self.path_fire_info[idx]["ff"] if ff then self.fire_forward = if_then_else(ff == "true", true, false) else self.fire_forward = false end local fb = self.path_fire_info[idx]["fb"] if fb then self.fire_backward = if_then_else(fb == "true", true, false) else self.fire_backward = false end local f = self.path_fire_info[idx]["f"] if f then self.state_shooting = if_then_else(f == "true", state_shooting_on, state_none) else self.state_shooting = if_then_else(self.st.auto_fire, state_shooting_on, state_none) end local ft = self.path_fire_info[idx]["ft"] if ft then self.fire_time = tonumber(ft) else self.fire_time = self.def_fire_time end else self.fire_forward = false self.fire_backward = false self.state_shooting = if_then_else(self.st.auto_fire, state_shooting_on, state_none) self.fire_time = def_min_fire_time end if self.fire_time > 0 then self.state_cannon = state_cannon_delay self.fire_start_time = time_global() --self:rot_to_firepoint(nil) self:set_shooting(self.state_shooting) else -- Выбрать следующую точку стрельбы: self.target_fire_pt_idx, self.target_fire_pt = self:get_next_firepoint() -- Если мы уже целимся в эту точку - не ждать апдейта, чтобы вызвать callback if self.target_fire_pt then self.state_cannon = state_cannon_rotate if self.fire_rot_dir == 1 and self.fire_forward or self.fire_rot_dir == -1 and self.fire_backward then self.state_shooting = state_shooting_on else self.state_shooting = state_none end self:rot_to_firepoint(self.target_fire_pt) self:set_shooting(self.state_shooting) else self.state_cannon = state_cannon_stop if self.state_shooting ~= state_none then self.state_shooting = state_none self:set_shooting(self.state_shooting) self:set_signal("fire_end") end end end end function action_car:set_signal(sig) local stor = db.storage[self.object:id()] stor[stor.active_scheme].signals[sig] = true end function angle_xz(npc, target_pos) local dir1 = npc:direction() dir1.y = 0 local dir2 = utils.vector_copy_by_val(target_pos):sub(npc:position()) dir2.y = 0 local dp = dir1:dotproduct(dir2) if dp < 0 then return math.pi - yaw(dir1, dir2) end return yaw(dir1, dir2) end function get_katet(npc, target_pos) local p = utils.vector_copy_by_val(target_pos):sub(npc:position()) local q = npc:direction() local k = p.x * q.x + p.y * q.y if k ~= 0 then return target_pos:distance_to(npc:position()) * (p.x * q.y - p.y * q.x) / k end return -1 end function action_car:fastcall() if db.storage[self.object:id()].active_scheme ~= "ph_car" then -- Если активная схема - не машина, снять быстрый апдейт return true end if self.usable ~= nil then local cu = xr_logic.pick_section_from_condlist(db.actor, self.object, self.usable.condlist) local u = (cu == "true" or cu == "") if u then if self.show_tips and self.tip_use then self.object:set_tip_text(self.st.tip_use) end elseif self.show_tips and self.tip_locked then self.object:set_tip_text(self.st.tip_locked) end self.object:set_nonscript_usable(u) return false end return self:fast_update() end function action_car:update(delta) --вставка2 self:update_friends_and_target() if xr_logic.try_switch_to_another_section(self.object, self.st, db.actor) then return end if self.destroyed then xr_logic.switch_to_section(self.object, self.st, "nil") return end if self.st.invulnerable then self.object.health = self.def_health end end function action_car:destroy_car() self.state_moving = state_moving_end self:stop_car() self.state_cannon = state_none self.state_firetarget = state_none self.state_shooting = state_none self.car:Action(CCar.eWpnAutoFire, 0) self:set_shooting(self.state_shooting) --turn off lights xr_logic.mob_capture(self.object, true) action(self.object, object("left_light", object.deactivate), cond(cond.time_end, time_infinite)) xr_logic.mob_capture(self.object, true) action(self.object, object("right_light", object.deactivate), cond(cond.time_end, time_infinite)) xr_logic.mob_release(self.object) if self.st.on_death_info ~= nil then db.actor:give_info_portion(self.st.on_death_info) end --вставка3 if self.st.on_death_func then loadstring(self.st.on_death_func)() end --вставка3 self.destroyed = true end -- Вернуть true, если апдейты больше не нужны function action_car:fast_update() --if not self.object:action() then --printf("_pc: CAR EXPLODE") --self.object:explode(0) --self.object:Explode() --end if self.car:GetfHealth() <= 0 then --printf("car <state>: killed.") --self:car_explode() self:destroy_car() return true end local cur_time = time_global() if self.fc_upd_num < def_max_fc_upd_num then local last_upd = self.fc_last_upd_tm if last_upd ~= -1 then local n = self.fc_upd_num if n < 3000 then self.fc_upd_avg = (self.fc_upd_avg * n + (cur_time - last_upd))/(n + 1) self.fc_upd_num = n + 1 else self.fc_upd_num = 1 end end self.fc_last_upd_tm = cur_time end if self.state_moving == state_moving_end and self.state_cannon == state_cannon_stop and self.state_firetarget == state_none then if xr_logic.mob_captured(self.object) and not self.object:action() then xr_logic.mob_release(self.object) if self.st.on_death_info ~= nil then db.actor:give_info_portion(self.st.on_death_info) end self:destroy_car() return true -- апдейты больше не нужны end return false end if self.state_moving ~= state_moving_end and self.state_moving ~= state_moving_stop and cur_time >= self.last_pos_time + self.min_car_explode_time then if not self.last_pos then self.last_pos = self.object:position() self.last_pos_time = cur_time else local cur_pos = self.object:position() local diff = self.last_pos:distance_to(cur_pos) if diff < self.min_delta_per_sec then -- застряли? if math.abs(self.object:direction().y) > 0.35 then if self.object:direction().x < 0 then self.turn = move.right else self.turn = move.left end xr_logic.mob_capture(self.object, true) action(self.object, move(move.fwd + self.turn, self.speed), cond(cond.time_end, time_infinite)) self.state_moving = state_moving_rot_right else self:stop_car() --self:car_explode() self.state_moving = state_moving_end --return false end else self.last_pos = cur_pos end self.last_pos_time = cur_time end end if self.state_moving ~= state_moving_end and self.state_moving ~= state_none then --printf("car <move>: try") if self.target_walk_pt >= 0 then if self:at_target_walkpoint() then --printf("car <move>: at target point") -- если нет флага ожидания стрельбы или мы уже отстрелялись или пошли в цикле обратно if not self.fire_wait or self.state_cannon == state_cannon_stop then --self.fire_rot_dir == -1 then --printf("car <move>: car go to the new point.") -- Прибыли, выбрать новую точку self:walk_arrival_callback(self.target_walk_pt) --printf("car <move>: new target = %s", utils.to_str(self.target_walk_pt)) -- меняем точки отстрела self:change_fire_pts() else --printf("car <move>: 1.car stopped.") if self.state_moving ~= state_moving_stop then self:stop_car() end self.state_moving = state_moving_stop end else --printf("car <move>: car keep going.") --get_console():execute(self.object:direction().z.."_"..self.object:direction().x.."_"..self.object:direction().y) if math.abs(self.object:direction().y) < 0.35 then self:go_to_walkpoint(self.target_walk_pt)-- Продолжать ехать, или поворачиваться end end else --printf("car <move>: 2.car stopped.") if self.state_cannon ~= state_cannon_stop then self:stop_car() self.state_moving = state_moving_stop end end end if self.hasWeapon then --printf("car <fire>: target(%d)", self.state_firetarget) if self.on_target_vis and self.on_target_vis.v1:alive() and self.car:IsObjectVisible(self.on_target_vis.v1) then --printf("car <vis>: try") local new_section = xr_logic.pick_section_from_condlist(db.actor, self.object, self.on_target_vis.condlist) if new_section then --printf("car <vis>: switch to section [%s]", new_section) xr_logic.switch_to_section(self.object, self.st, new_section) end end if self.on_target_nvis and self.on_target_nvis.v1:alive() and not self.car:IsObjectVisible(self.on_target_nvis.v1) then --printf("car <nvis>: try") local new_section = xr_logic.pick_section_from_condlist(db.actor, self.object, self.on_target_nvis.condlist) if new_section then --printf("car <nvis>: switch to section [%s]", new_section) xr_logic.switch_to_section(self.object, self.st, new_section) end end if self.state_firetarget == state_firetarget_points then if self.fire_pt_count > 0 and self.state_cannon ~= state_cannon_stop then --printf("car <fire>: shooting points") if self.state_cannon == state_cannon_delay then if self.fire_start_time + self.fire_time < cur_time then --printf("car <fire>: stop delaying(%.2f + %.2f < %.2f)", self.fire_start_time, self.fire_time, time_global()) --printf("car <fire>: 1.new fire point.") self:fire_arrival_callback(self.target_fire_pt_idx) else --printf("car <fire>: delaying(%.2f + %.2f < %.2f)", self.fire_start_time, self.fire_time, cur_time) end else if self.car:CanHit() or self.target_fire_pt_idx == 0 then --printf("car <fire>: 2.new fire point.") -- Прибыли, выбрать новую точку self:fire_arrival_callback(self.target_fire_pt_idx) end end end elseif self.state_firetarget == state_firetarget_enemy then --вставка4 local target_dist = self.object:position():distance_to_sqr(self.target_obj:position()) local has_friends_on_fire_line = self:check_friends_on_fire_line() if self.target_obj:alive() and target_dist <= self.fire_range_sqr and self.car:IsObjectVisible(self.target_obj) and not has_friends_on_fire_line then self.target_fire_pt = self:extrapolate_pos(self.target_obj) self:rot_to_firepoint(self.target_fire_pt) --вставка4 if self.car:CanHit() then if self.state_shooting == state_none then self.state_shooting = state_shooting_on self:set_shooting(self.state_shooting) --self:set_signal("fire_start") end else if self.state_shooting ~= state_none then self.state_shooting = state_none self:set_shooting(self.state_shooting) --self:set_signal("fire_end") end end else if self.state_shooting ~= state_none then self.state_shooting = state_none self:set_shooting(self.state_shooting) --self:set_signal("fire_end") end if self.fire_track_target then self.target_fire_pt = self:extrapolate_pos(self.target_obj) self:rot_to_firepoint(self.target_fire_pt) end end end end return false end --вставка5 function action_car:extrapolate_pos(obj) local mypos = self.object:position() if not self.prev_pos then self.prev_pos = obj:bone_position("bip01_spine1") self.prev_delta = vector():set(0,0,0) end local curpos = obj:bone_position("bip01_spine1") local hcorr = mypos:distance_to_sqr(curpos)/180/180*1.3 local delta = obj:bone_position("bip01_spine1"):sub(self.prev_pos) self.prev_delta:mul(1):add(delta):mul(0.5) local extrapos = vector():set(self.prev_delta.x,self.prev_delta.y,self.prev_delta.z):mul(10):add(curpos):add(vector():set(0,hcorr,0)) self.prev_pos = curpos return extrapos end --вставка5 function action_car:car_explode() self.object:explode(time_global()) end function action_car:net_destroy() --self:destroy_car() if self.object and xr_logic.mob_captured(self.object) then xr_logic.mob_release(self.object) if self.st.on_death_info ~= nil then db.actor:give_info_portion(self.st.on_death_info) end --вставка6 if self.st.on_death_func then loadstring(self.st.on_death_func)() end end --вставка6 end --вставка7 function action_car:check_friends_on_fire_line() if self.target_fire_pt then local pos = self.object:bone_position("mashine_gun_fire_point") local dir_aim = vector():set(self.target_fire_pt.x - pos.x, self.target_fire_pt.y - pos.y , self.target_fire_pt.z - pos.z) local target_dist = pos:distance_to(self.target_obj:position()) --проверяем позиции солдат и текущего сектора обстрела for a,v in pairs(self.friends) do tmp = level.object_by_id(a) if tmp and tmp:alive() then local pos_soldier = tmp:position() local radius = 4 if v=="vehicle_btr" then radius = 4 else radius = 1.7 end local friend_dist=self.object:position():distance_to(pos_soldier)-radius if friend_dist < target_dist then --считаем попадает ли текущий солдат в сектор обстрела local dir_soldier = vector():set(pos_soldier.x - pos.x, pos_soldier.y - pos.y , pos_soldier.z - pos.z) local x = dir_soldier.x*dir_aim.x+dir_soldier.z*dir_aim.z local y = -dir_soldier.z*dir_aim.x+dir_soldier.x*dir_aim.z -- повернули систему координат local angle = math.atan2(y,x) -- угол доворота от -180 до 180 local div = radius/friend_dist if angle >= -div and angle <= div then return true end end end end end return false end function action_car:update_friends_and_target() if self.st.fire_target == "monsters" then for k in pairs(db.monster_stock) do local obj = level.object_by_id(k) if obj and IsMonster(obj) and obj:alive() and self.car:IsObjectVisible(obj) then self.target_obj = obj self.state_firetarget = state_firetarget_enemy end end end --изъят блок с вариантом стрельбы БТРов по ведролётам if self.st.fire_target == "stalker_group" then --for a=1,65534,1 do --local obj = level.object_by_id(a) for k in pairs(db.creature) do local obj = level.object_by_id(k) if obj and IsStalker(obj) and obj:alive() and obj:character_community()=="stalker" and self.car:IsObjectVisible(obj) then self.target_obj = obj self.state_firetarget = state_firetarget_enemy end end end end --вставка7 function add_to_binder(npc, ini, scheme, section, storage) local new_action = action_car(npc, storage) -- Зарегистрировать все actions, в которых должен быть вызван метод reset_scheme при изменении настроек схемы: xr_logic.subscribe_action_for_events(npc, storage, new_action) end function set_scheme(npc, ini, scheme, section, gulag_name) local st = xr_logic.assign_storage_and_bind(npc, ini, scheme, section) st.logic = xr_logic.cfg_get_switch_conditions(ini, section, npc) st.usable = xr_logic.cfg_get_condlist(ini, section, "usable", npc) if st.usable == nil then st.path_walk = utils.cfg_get_string(ini, section, "path_walk", npc, false, gulag_name) st.path_fire = utils.cfg_get_string(ini, section, "path_fire", npc, false, gulag_name, nil) st.auto_fire = utils.cfg_get_bool(ini, section, "auto_fire", npc, false, false) st.fire_time = utils.cfg_get_number(ini, section, "fire_time", npc, false, def_min_fire_time) st.fire_rep = utils.cfg_get_string(ini, section, "fire_repeat", npc, false, gulag_name, nil) st.fire_range = utils.cfg_get_number(ini, section, "fire_range", npc, false, def_fire_range) st.fire_target = utils.cfg_get_string(ini, section, "target", npc, false, gulag_name, "points") st.fire_track_target = utils.cfg_get_bool(ini, section, "track_target", npc, false, false) st.on_target_vis = xr_logic.cfg_get_string_and_condlist(ini, section, "on_target_vis", npc) st.on_target_nvis = xr_logic.cfg_get_string_and_condlist(ini, section, "on_target_nvis", npc) st.path_walk_info = nil -- Будут инициализированы в reset(), сейчас пути могут быть еще не загружены. st.path_fire_info = nil else st.show_tips = utils.cfg_get_bool(ini, section, "show_tips", npc, false, true) st.tip_use = utils.cfg_get_string(ini, section, "tip_use", npc, false, "", "tip_car_use") st.tip_locked = utils.cfg_get_string(ini, section, "tip_locked", npc, false, "", "tip_car_locked") end st.invulnerable = utils.cfg_get_bool(ini, section, "invulnerable", npc, false, false) st.headlights = utils.cfg_get_string(ini, section, "headlights", npc, false, gulag_name, "off") st.on_death_info = utils.cfg_get_string(ini, section, "on_death_info", npc, false, gulag_name, nil) --вставка8 st.on_death_func = utils.cfg_get_string(ini, section, "on_death_func", npc, false, gulag_name, nil) end Ну и к нему: Скрытый текст --[[--------------------------------------------------------------- База данных живых онлайновых объектов, зон и рестрикторов, актёра Чугай Александр Апдейт под нужды R.M.A. Апдейт под нужды логики работы БТР -----------------------------------------------------------------]] zone_by_name = {} sl_by_name = {} storage = {} sound = {} actor = nil actor_proxy = actor_proxy.actor_proxy() heli = {} camp_storage = {} story_by_id = {} smart_terrain_by_id = {} trader = nil info_restr = {} strn_by_respawn = {} creature = {} -- true - человек, false - животное (исключая торговца) monster_stock = {} FlagEsc = 0 Flag2 = 0 Dead2 = 0 function add_obj( obj ) if IsStalker(obj) then creature[obj:id()] = true elseif IsMonster(obj) then monster_stock[obj:id()] = true end end function del_obj( obj ) storage [obj:id()] = nil if IsStalker(obj) then creature[obj:id()] = nil elseif IsMonster(obj) then monster_stock[obj:id()] = nil end end function add_zone( zone ) zone_by_name[zone:name()] = zone add_obj( zone ) end function del_zone( zone ) zone_by_name[zone:name()] = nil del_obj( zone ) end function add_sl( sl ) sl_by_name[sl:name()] = sl add_obj( sl ) end function del_sl( sl ) sl_by_name[sl:name()] = nil del_obj( sl ) end function add_actor( obj ) actor = obj actor_proxy:net_spawn( obj ) add_obj( obj ) end function del_actor() del_obj( actor ) actor_proxy:net_destroy() actor = nil end function add_heli(obj) heli[obj:id()] = obj end function del_heli(obj) heli[obj:id()] = nil end function add_smart_terrain( obj ) smart_terrain_by_id[obj.id] = obj end function del_smart_terrain( obj ) smart_terrain_by_id[obj.id] = nil end Знаю, что косо, криво, коряво и пр., но оно работает, вроде как без вылетов. БТР может стрелять по ГГ, монстрам или группировкам. 5 Ссылка на комментарий
Pir@t@s 36 Опубликовано 1 Ноября 2021 Поделиться Опубликовано 1 Ноября 2021 День добрый товарищи. У меня вопрос, вот какого плана: Как установить метку на предмет, если использовать «Рандомный спавн объектов» от тов. Singapur22? Пример функции: function my_spawn() local tbl = { {129.204,-6.337,-12.101,427496,133}, {101.002,-7.632,-4.966,398683,116}, {106.678,-7.494,8.702,406288,118} } local items = { 'af_medusa', 'af_vyvert', 'af_blood' } xr_effects.uni_random_spawn(items, tbl, kol) end Ссылка на комментарий
I am Dead 918 Опубликовано 1 Ноября 2021 Поделиться Опубликовано 1 Ноября 2021 @Pir@t@s Функцию из xr_effects покажи Ссылка на комментарий
Pir@t@s 36 Опубликовано 1 Ноября 2021 Поделиться Опубликовано 1 Ноября 2021 @I am Dead https://disk.yandex.ru/d/QTFcsaIC8tGV2g И прощу прощения, забыл указать: Игра ТЧ 1.0006@I am Dead Ссылка на комментарий
AndreySol 215 Опубликовано 1 Ноября 2021 Поделиться Опубликовано 1 Ноября 2021 @Pir@t@s В начале uni_random_spawn объявить переменную: local cse_obj -- она будет хранить спец. объект класса для создаваемых предметов Затем изменить строки создания предметов: cse_obj = alife():create(item, pos, lv_id, gv_id, id) Далее, в конце ф-ции uni_random_spawn добавить установку метки, к примеру ставим метку на серверный объект: level.map_add_object_spot_ser(cse_obj.id, type, text) Описание аргументов ф-ции уст. метки смотрим в Справочнике по ф-циям и классам. 1 1 1 Ссылка на комментарий
I am Dead 918 Опубликовано 1 Ноября 2021 Поделиться Опубликовано 1 Ноября 2021 @Pir@t@s Скрытый текст function uni_random_spawn(items, tbl, kol) local lv_id, gv_id, obj, item, ms, kol2 local kol1 = 1 local id = 65535 local pos = vector() if type(tbl) == 'table' then ms = math.random(#tbl) end if type(tbl) == 'table' and type(tbl[ms]) == 'table' then pos.x = tbl[ms][1] pos.y = tbl[ms][2] pos.z = tbl[ms][3] lv_id = tbl[ms][4] gv_id = tbl[ms][5] else if type(tbl) == 'table' and type(tbl[ms]) == 'number' then ms = tbl[ms] obj = level_object_by_sid (ms) elseif type(tbl) == 'table' and type(tbl[ms]) == 'string' or type(tbl) == 'string' then obj = db.actor elseif type(tbl) == 'number' then obj = level_object_by_sid (tbl) end pos = obj:position() lv_id = obj:level_vertex_id() gv_id = obj:game_vertex_id() id = obj:id() end if kol == nil then kol = 1 end for s=1, kol do if type(items) == 'table' then item = math.random(#items) if type(items[item]) == 'number' then item = item - 1 end if type(items[item+1]) == 'number' then kol1 = items[item+1] end item = items[item] else item = items end for i=1, kol1 do if type(item) == 'table' then for k, v in ipairs(item) do if type(item[k+1]) == 'number' then kol2 = item[k+1] else kol2 = 1 end if type(item[k]) ~= 'number' then for j=1, kol2 do local obj = alife():create(v, pos, lv_id, gv_id, id) add_spot_on_map(obj.id, "red_location", "Твой текст") end end end else local obj = alife():create(item, pos, lv_id, gv_id, id) add_spot_on_map(obj.id, "red_location", "Твой текст") end end end end function add_spot_on_map(obj_id,type,text) --+ --возможные типы type смотри в ui\map_spots.xml if obj_id then if text==nil then text=" " end -- Ставим метку на серверный объект чтобы её не пришлось обновлять level.map_add_object_spot_ser(obj_id, type, text) end end 1 Ссылка на комментарий
Colder 12 Опубликовано 3 Ноября 2021 Поделиться Опубликовано 3 Ноября 2021 Может кто подсказать, почему сообщение приходит из секции патронов а не так как в text(имя) ? Скрытый текст function on_weapon_ammo(wpn) local active_item = db.actor:item_in_slot(db.actor:active_slot()) if active_item then local ammo_type = ca_get_weapon_ammo_type( alife():object(wpn:id())) local section_ammo = ca_ammo_by_num(wpn:section(),ammo_type) if section_ammo~=nil and string.find(section_ammo,"ammo") then get_hud():AddCustomStatic("text2", true):wnd():SetText("%c[cyan]"..gts("st_ammo_string_0_1").."\\n".."%c[default]"..gts(section_ammo)) end end end Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти