Капрал Хикс 558 Опубликовано 30 Апреля 2021 20 минут назад, Kirgudu сказал(а): Ничего не смущает? Ох уж этот чужой код... Да, там лучше or поставить, думаю. 1 Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 19 Мая 2021 Я тут снова по поводу боевой схемы БТРов... Немного, КМК, разобрался в её работе, в итоге в db.script: Скрытый текст creature = {} monster_stock = {} function add_obj( obj ) - корректно ли тут производится проверка и добавление сталкеров и монстров? if IsStalker(obj) then creature[obj:id()] = true monster_stock[obj:id()] = false elseif IsMonster(obj) then creature[obj:id()] = false monster_stock[obj:id()] = true end end function del_obj( obj ) storage [obj:id()] = nil if IsStalker(obj) or IsMonster(obj) then creature[obj:id()] = nil end end Собственно не очень красивая функция апдейта друзей и врагов в ph_car.script: Скрытый текст 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 По ней такой вопрос... if obj and IsMonster(obj) and obj:alive() and self.car:IsObjectVisible(obj) then if obj and IsStalker(obj) and obj:alive() and obj:character_community()=="stalker" and self.car:IsObjectVisible(obj) then - тут вроде выделенные жирным проверки лишние? Ведь если объекты берутся из for k in pairs(db.monster_stock) и for k in pairs(db.creature) do, там же уже была соотв. проверка: function add_obj( obj ) if IsStalker(obj) then creature[obj:id()] = true monster_stock[obj:id()] = false elseif IsMonster(obj) then creature[obj:id()] = false monster_stock[obj:id()] = true end end Просьба не пинать :), хочу разобраться и сделать идеальный ph_car.script с рабочей боевой схемой и правками от переворачивания машин. Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 25 Мая 2021 Помогите разобраться, а то я забуксовал на ровном месте. Дано: скрипт использования предметов со звуками. Мне нужно следующее: при использовании определённого предмета и наличии двух инфопоршней проигрывать звук и выполнять функцию из другого скрипта, если поршней нет - не играть звук и спавнить предмет обратно в инвентарь (он съедобный, на классе антирада). Вот скрипт в упрощённом виде: Скрытый текст local tSound ={ cocacola = "scripts\\inv_drinking",item = "scripts\\inv_item" - предмет и звук для него } function using_items(obj) local sect = obj:section() local actor = db.actor if obj and tSound[obj:section()] then local snd = xr_sound.get_safe_sound_object(tSound[obj:section()]) if snd then snd:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 2.0) end end if obj then if sect == "item" then if has_alife_info("info_1") and - поршень 1 has_alife_info("info_2") then - поршень 2 script.final_action() - выполнить функцию из другого скрипта end else amk.spawn_item_in_inv("item") - спавн обратно в инвентарь end end end Сейчас без наличия инфопоршней предмет просто "съедается" и звук всё равно проигрывается.... Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 1 Июня 2021 1 час назад, Купер сказал(а): на предмет обдумывания о целесообразности использования. Пока вполне подходит при употреблении многих предметов за раз. Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 13 Июля 2021 Не нахожу поиском или туплю. В ТЧ есть скриптовый метод проверки ГГ на кровотечение? Задумал тут перетащить медиков из ЗП... if db.actor.bleeding > 0 then -такая проверка вообще возможна в ТЧ? Ну и сам скрипт лечения: function medic_magic_potion(first_speaker, second_speaker) db.actor.health = 1 db.actor.power = 1 db.actor.radiation = -1 db.actor.bleeding = 1 end Будет ли работать в ТЧ? Где подсмотреть? Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 14 Июля 2021 (изменено) @AndreySol @Zander_driver , я тут поразмыслил, и понял, что лучше всего использовать банальную проверку на состояние здоровья ГГ <1.0 (ну и радиации). Ведь если у ГГ есть кровотечение, то здоровье всё равно будет ниже единицы? А насчёт записи состояния кровотечения - в x-ray extension вроде добавлен метод: // CEntityAlive heal_wounds(float) Кстати, в R.M.A. по идее он должен работать, только как правильно вызвать функцию остановки кровотечения? Изменено 14 Июля 2021 пользователем Капрал Хикс Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 14 Июля 2021 12 минут назад, AndreySol сказал(а): Например от голода - разве это признак ранения? Мне всё равно нужен универсальный метод проверки, нуждается ли ГГ в лечении. Неважно, от чего здоровье будет ниже единицы. 15 минут назад, AndreySol сказал(а): что там в x-ray extension накрутили - надо в описании и читать. // CEntityAlive heal_wounds(float) - там вот так и описано, что-де добавлен метод такой. Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 25 Августа 2021 Как скриптом зажечь фары у стоящей машины, в которой не сидит ГГ? Движок x-ray extensions. Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 15 Октября 2021 Дано: скрипт ругани ГГ при заклинивании ствола (ТЧ). Отслеживается наличие статика о клине. Скрытый текст function jammed_weapon() local hud = get_hud() local custom_static = hud:GetCustomStatic("gun_jammed") if rma_options.jam_sound and custom_static ~= nil then local rnd = math.random(1,6) local snd if rnd == 1 then snd = xr_sound.get_safe_sound_object([[actor\jam_1]]) elseif rnd == 2 then snd = xr_sound.get_safe_sound_object([[actor\jam_2]]) elseif rnd == 3 then snd = xr_sound.get_safe_sound_object([[actor\jam_3]]) elseif rnd == 4 then snd = xr_sound.get_safe_sound_object([[actor\jam_4]]) elseif rnd == 5 then snd = xr_sound.get_safe_sound_object([[actor\jam_5]]) elseif rnd == 6 then snd = xr_sound.get_safe_sound_object([[actor\jam_6]]) end snd:play_at_pos(db.actor, vector():set(0,0,0), 0, sound_object.s2d) end end Знаю, что код корявый. Но проблема в том, что в таком виде рандомные звуки, перекрывая друг друга, играют, пока статик не исчезнет. И вот как бы так хитро отследить факт появления статика, что ли, а не его наличия. Чтобы проверка не запускала звуки все те несколько секунд, пока он есть... Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 16 Октября 2021 12 минут назад, AndreySol сказал: из многострадального апдейта? Да, но опять-таки если подскажете более удобный способ... Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 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 Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 18 Ноября 2021 Всем привет. Решил тут прикрутить-таки звуки приветствия и прощания Сахарову для ТЧ, на манер ЧН... Скрытый текст --дописано yan_professor_hello = {min_snd = 1, max_snd = 1, rnd = 100, prior = 5, rnd_id = id(), into_id = id(), max_ids = {}}, yan_professor_goodbye = {min_snd = 1, max_snd = 1, rnd = 100, prior = 5, rnd_id = id(), into_id = id(), max_ids = {}}, Скрытый текст --дописано [yan_professor_hello_rnd] yan_general_ecolog = 0,scenario\yantar\yan_sakharov_meet_ [yan_professor_goodbye_rnd] yan_general_ecolog = 0,scenario\yantar\yan_sakharov_meet_bye_ Соотв. звуки добавлены в нужную папку. А вот с файлом логики Сахарова у меня непонятки. Скрытый текст [logic] active = walker@yan_start actor_dialogs = actor_dialogs combat_ignore = combat_ignore trade = misc\trade_ecolog.ltx inv_max_weight = 10000 [walker@yan_start] path_walk = yan_ucheniy_walk_talk path_look = yan_ucheniy_look_talk combat_ignore_cond = always on_info = {-yantar_kruglov_phrase_2 +yantar_scientists_talk} remark@yan_professor_talk_1 on_info2 = {+yantar_kruglov_phrase_2} walker@yan_1 danger = danger_condition@yan_ecolog def_state_standing = yan_professor_wait def_state_moving1 = yan_professor_walk def_state_moving2 = yan_professor_walk def_state_moving3 = yan_professor_walk meet = no_meet [remark@yan_professor_talk_1] snd = yantar_professor_to_kruglov_1 anim = yan_professor_wait target = logic@scientist_out_rest, yan_scientist on_timer = 5000 | %+yantar_kruglov_phrase_1% on_info = {+yantar_professor_phrase_2} remark@yan_professor_talk_2 combat_ignore_cond = always danger = danger_condition@yan_ecolog meet = no_meet [remark@yan_professor_talk_2] snd = yantar_professor_to_kruglov_2 anim = yan_professor_wait target = logic@scientist_out_rest, yan_scientist on_timer = 5000 | walker@yan_1 %+yantar_kruglov_phrase_2% combat_ignore_cond = always danger = danger_condition@yan_ecolog meet = no_meet [walker@yan_1] path_walk = yan_ucheniy_walk path_look = yan_ucheniy_look combat_ignore_cond = always on_info = {+yan_actor_talk_ucheniy} walker@yan_2 on_info2 = {+yan_find_scientist_done} walker@scientist_quest_good danger = danger_condition@yan_ecolog def_state_standing = yan_professor_wait def_state_moving1 = yan_professor_walk def_state_moving2 = yan_professor_walk def_state_moving3 = yan_professor_walk meet = meet@yan_general_scientist_1 ;Дописано on_actor_dist_le = 2 | remark@yan_professor_hello on_actor_dist_ge = 4 | remark@yan_professor_goodbye [walker@scientist_quest_good] path_walk = yan_ucheniy_walk_talk path_look = yan_ucheniy_look_talk combat_ignore_cond = always on_info = {+yantar_scientist_talk_helmet} remark@talk_about_helmet danger = danger_condition@yan_ecolog def_state_standing = yan_professor_wait def_state_moving1 = yan_professor_walk def_state_moving2 = yan_professor_walk def_state_moving3 = yan_professor_walk meet = meet@yan_general_scientist_1 ;Дописано on_actor_dist_le = 2 | remark3@yan_professor_hello on_actor_dist_ge = 4 | remark3@yan_professor_goodbye [remark@talk_about_helmet] snd = yantar_professor_radiation_quest_2 anim = yan_professor_wait target = logic@scientist_out_rest, yan_scientist meet = no_meet combat_ignore_cond = always on_signal = sound_end | walker@go_to_room %-yantar_scientist_talk_helmet% danger = danger_condition@yan_ecolog [walker@go_to_room] path_walk = yan_general_scientist_room_walk path_look = yan_general_scientist_room_look on_signal = make_helmet | remark@make_helmet combat_ignore_cond = always danger = danger_condition@yan_ecolog meet = no_meet def_state_standing = yan_professor_wait def_state_moving1 = yan_professor_walk def_state_moving2 = yan_professor_walk def_state_moving3 = yan_professor_walk [remark@make_helmet] anim = mode_shlem target = 920 combat_ignore_cond = always on_signal = action_end | walker@go_to_actor danger = danger_condition@yan_ecolog meet = no_meet [walker@go_to_actor] path_walk = yan_ucheniy_walk_talk path_look = yan_ucheniy_look_talk combat_ignore_cond = always on_info = {+yan_kill_brain_task_start} walker@yan_2 danger = danger_condition@yan_ecolog def_state_standing = yan_professor_wait def_state_moving1 = yan_professor_walk def_state_moving2 = yan_professor_walk def_state_moving3 = yan_professor_walk meet = meet@yan_general_scientist_1 ;Дописано on_actor_dist_le = 2 | remark3@yan_professor_hello on_actor_dist_ge = 4 | remark3@yan_professor_goodbye [walker@yan_2] path_walk = yan_ucheniy_walk_talk path_look = yan_ucheniy_look_talk combat_ignore_cond = always on_info = {-yan_actor_talk_ucheniy} walker@yan_1 on_info2 = {+yantar_scientist_talk_helmet} remark@talk_about_helmet meet = meet@yan_general_scientist_1 danger = danger_condition@yan_ecolog def_state_standing = yan_professor_wait def_state_moving1 = yan_professor_walk def_state_moving2 = yan_professor_walk def_state_moving3 = yan_professor_walk [meet@yan_general_scientist] meet_state = 2 | yan_professor_wait@yantar_professor_talk_1 meet_state_wpn = 2 | yan_professor_wait@yantar_professor_talk_1 victim = 2 | actor victim_wpn = nil use = true use_wpn = false [meet@yan_general_scientist_1] meet_state = 1 | yan_professor_wait@yantar_professor_talk_1 meet_state_wpn = 1 | yan_professor_wait@yantar_professor_talk_1 victim = 1 | actor victim_wpn = nil use = true use_wpn = false abuse = false precond = usability [meet@no_talk] meet_state = 1 | yan_professor_wait@yantar_professor_talk_1 meet_state_wpn = 1 | yan_professor_wait@yantar_professor_talk_1 victim = 1 | actor victim_wpn = nil use = false use_wpn = false abuse = false [danger_condition@yan_ecolog] ignore_distance = 0 [actor_dialogs] id = yantar_general_ucheniy_talk_start,yantar_general_ucheniy_talk_end [combat_ignore] combat_ignore_cond = always ;Дописано [remark@yan_professor_hello] anim = yan_professor_wait snd = yan_professor_hello on_signal = sound_end | walker@yan_1 [remark@yan_professor_goodbye] anim = yan_professor_wait snd = yan_professor_goodbye on_signal = sound_end | walker@yan_1 [remark2@yan_professor_hello] anim = yan_professor_wait snd = yan_professor_hello on_signal = sound_end | walker@yan_2 [remark2@yan_professor_goodbye] anim = yan_professor_wait snd = yan_professor_goodbye on_signal = sound_end | walker@yan_2 [remark3@yan_professor_hello] anim = yan_professor_wait snd = yan_professor_hello on_signal = sound_end | walker@scientist_quest_good [remark3@yan_professor_goodbye] anim = yan_professor_wait snd = yan_professor_goodbye on_signal = sound_end | walker@scientist_quest_good В общем, при приближении ближе 2 метров по идее должен здороваться, при удалении более чем на 4 метра прощаться. Но работает только прощание изредка и то при этом, Сахарова можно поймать при подходе к столу так, что будет звучать только рандомное прощание. Где я с логикой накосячил? 1 Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 4 Декабря 2021 И всё-таки что за ерунда с вылетом вида: stack trace: 0023:05175AF0 xrGame.dll [error][ 87] : Параметр задан неверно. Делаем квиксейв клавишей F6, при попытке загрузиться с него клавишей F7 (или другой назначенной) - вылет выше, при попытке загрузиться с него из меню - всё грузится нормально... Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 5 Декабря 2021 7 часов назад, mole venomous сказал: Ну вот очень знакомые слова. Страница 556 этой темы, я уже сталкивался с подобным и мне помогли, а тут опять эта ерунда вылезла. Клавиша быстрой загрузки роли не играет, пробовал назначить F9 - та же петрушка с вылетом. Из меню грузится нормально. Ерунда какая-то... Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 8 Декабря 2021 Может такое быть, что вылет вида: stack trace: 0023:05175AF0 xrGame.dll [error][ 87] : Параметр задан неверно. вызван тем, что какой-то из скриптов сохранён в формате UTF-8, а не ANSI? Я просто не знаю, на что подумать ещё. Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 7 Января 2022 А подскажите вот по вылету вида: [error]Expression : e_entity->ID_Parent == id_parent [error]Function : xrServer::Process_event_reject [error]File : E:\stalker\sources\trunk\xr_3da\xrGame\xrServer_process_event_reject.cpp [error]Line : 23 [error]Description : wpn_walther12350 [error]Arguments : rad_tramplin_walker4 Вылет происходит именно при обыске трупов. Справочник гласит, что: "такое порой случается, когда или объект удаляется из игры без требуемой отрегистрации. А бороться можно только выверяя все коды, в которых удаляются предметы/объекты на предмет необходимых отрегистраций." Но я что-то туплю, какие объекты могут удаляться при обыске трупа, а не во время смерти NPC например? Сдаётся, что причина какая-то банальная... Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 8 Января 2022 57 минут назад, AndrewMor сказал: Попробуй загрузить последний сейв и перепройти. Так-то оно работает, но вылет частенько случается с рандомными предметами в строке [error]Description : wpn_walther12350, бесит этим. Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 8 Января 2022 4 минуты назад, DenVer сказал: Если я правильно понимаю ситуацию, то в вылете виноват ствол Вальтер. Насколько я понял, у народа в моей сборке вылет с разными стволами и предметами происходит. 5 минут назад, DenVer сказал: посоветовать покопаться в этом направлении. Да вот пытаюсь. 5 минут назад, DenVer сказал: И да, меня смущает его номер, какой-то супер-уникальный Вальтер получается. Насколько я знаю, так движок маркирует отдельные предметы для себя, такой секции нет. Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 8 Января 2022 8 минут назад, DenVer сказал: Значит, разрабы накосячили с движком. Да не в этом дело. Это типа служебное обозначение предмета... Ладно, будем ещё посмотреть. 1 Поделиться этим сообщением Ссылка на сообщение
Капрал Хикс 558 Опубликовано 8 Января 2022 Увы, человек мою сборку уже удалил, пройдя (тема Hicks Compilation 1.0 на ap-pro для ясности). Пишет, что "если по памяти, то был замешан вальтер и в 90 случаях из 100 обыск монолитовцев." Всё же только этот злосчастный пистоль, простите за дезу. Я не особо много скриптовых изменений по оружию вносил, вот сижу думаю теперь, где этот пистолет мог накосячить. Грешу либо на фишку с выпадением оружия из рук NPC при попадании им в руку (но тогда бы не один вальтер глючил) либо думаю дальше. Кстати, знающие движок люди, проясните пожалуйста окончательно момент с указанием кол-ва патронов (или гранат) в character_desc_, там есть разница, ставить: ammo_9x19_fmj = 1 \n или же: ammo_9x19_fmj \n ? Поделиться этим сообщением Ссылка на сообщение