Dennis_Chikin 3 665 Опубликовано 29 Ноября 2014 (изменено) Ну вот как-то так уж, что-ли. Не проверял, ибо где я в такую погоду найду вам кровососа, да еще и извращенца ? local tg = time_global() -- должно быть сразу после function что-то_там( что_попало ) local mob = self.object -- и дальше заменяем все self.object на mob до конца функции --/#+# 'засос кровососа боксёра' -------------------------------------------------- if mob:clsid() == clsid.bloodsucker_s and mob.health > 0.25 then if self.attack_time and tg < self.attack_time -- атака пошла local enemy = mob:get_enemy() if enemy and enemy:id() == 0 and mob:see( enemy ) -- видит актора and enemy:position():distance_to_sqr( mob() ) < 4.3 then -- близко if self.timer_hit then if self.timer_hit < tg then -- наносим хит self.timer_hit = tg + 50 -- повторим потом local vDir = mob:direction() --/ вектор кровососа local vDirHit = vector_rotate_y( vDir, 179.0 ) local h = hit() h.draftsman = mob h.direction = vDirHit --/ направление хита h:bone( "bip01_spine" ) --/ для учета 'брони' h.power = 0.02 level.add_cam_effector( "camera_effects\\fusker.anm", 959, false, "" ) h.impulse = 50 / enemy:position():distance_to( mob() ) --/ чем ближе - тем сильнее пинаем h.type = hit.wound enemy:hit(h) --/ наносим хит жертве --/ разворот жертвы на кровососа. TODO: требует доработки/замены! enemy:set_actor_direction( vDirHit:getH() ) end else -- запуск анимации if mob:animation_count() ~= 0 then mob:clear_animations() end -- анимации остановили mob:add_animation( "wounded_2_out" ) --/ варианты: "vampire_0" | "idle" --/ озвучка 'засоса' local snd= sound_object( "material\\dead-body\\collide\\hithard06hl" ) if snd then snd:play_no_feedback( enemy, sound_object.s2d, 0, vector(), 5.0 ) end self.timer_hit = tg + 200 -- отыграет анимку, и нанесет хит end else self.attack_time = false -- атака сорвалась end elseif ( self.check_attack or 0 ) < tg then -- проверяем не постоянно local enemy = mob:get_enemy() if enemy and enemy:id() == 0 and mob:see( enemy ) -- видит актора and enemy:position():distance_to_sqr( mob() ) < 4.3 then -- близко self.attack_time = tg + 500 -- атака пошла, пол секунды на все self.check_attack = tg + 1000 -- ну и повтор через секунду self.timer_hit = false else self.check_attack = tg + 200 -- хотя бы 200ms end end end upd: 22:15 - и еще поправил. Ибо нефиг прямо на форуме код писать. И, блин, нет ничего хуже, чем постоянно что-то править под древние кривые скрипты, когда у тебя давно вменяемые написаны. 8( 2 Zander_driver: на риторический вопрос я могу дать только риторический ответ. Надо ? По тому что про кровососа был пост на форуме, и этого самого кровососа пытаются впихнуть именно в древний кривой скрипит. Upd2: тьфу, блин. if self.attack_time and tg < self.attack_time -- атака пошла вот так надо. И дальше тоже на attack_time поменять, для красивости. Изменено 29 Ноября 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 2 Декабря 2014 (изменено) Ну и вообще, если я правильно понял смысл поста, то это давно делают примерно так: local t_opt = { ["p"] = { "game_pause", "radio_amk_pause", 1 }, ["r"] = { "show_rad", "radio_amk_rad", 1, bind_stalker.rdet_enable }, ["h"] = { "suit_hud", "radio_amk_hud", 0 }, ["m"] = { "din_music", "radio_amk_mus", 0 }, ["a"] = { "keep_anoms", "radio_amk_anoms", 0 }, ["d"] = { "ch_difficulty", nil, 0 }, ["t"] = { "treasure_type", "radio_amk_treasure", 2 } } function save_options() local fs = getFS() local flist = fs:file_list_open_ex("$game_saves$", bit_or(FS.FS_ListFiles, FS.FS_RootOnly), "game_options_*.sta" ) local s = flist:GetAt( 0 ):NameFull() local opt = "" local n, fn for k, v in pairs( t_opt ) do n = v[3] if n == 0 then game_options[ v[1] ] = false fn = v[4] if fn then fn( false ) end else game_options[ v[1] ] = n fn = v[4] if fn then fn( n ) end end opt = opt .. k .. tostring( n ) end n = "game_options_" .. opt .. ".sta" if s ~= n then fs:file_rename( fs:update_path("$game_saves$", s ), fs:update_path("$game_saves$", n ), true) end end -- здесь, в частности, чтобы сохранить опции игры независимо от сэйвов. Изменено 2 Декабря 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 3 Декабря 2014 Просто метод более ограничен, чем другие. Например, вместе со всеми путями здесь не может быть более 250 символов. На сами символы тоже есть ограничения. То есть, это гораздо ХУЖЕ нетпакета. И хуже внешнего конвертера лога в ltx. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 11 Декабря 2014 (изменено) function kill(actor, npc) npc:kill(esc_paren_npc) end esc_paren_npc - это что ? И вообще, я не понял смысл всей конструкции. если есть онлайновый npc, и его надо убить - пишем ровно вот это npc:kill(npc) - ВСЕ. Вот в том самом месте, где таки надо убить. Если непись в офлайне - идем изучать работу с нетпакетами. 2 BlooderDen: Вот слегка не понял. В конфигах костюмов есть строки, касающиеся выносливости: восстановление actor.power от максимума за тик (таки в добавок к восстановлению самого актора, в конфиге именно актора), и k потери выносливости от веса тащимого. Надо-то что ? Изменено 11 Декабря 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 12 Декабря 2014 (изменено) Если это про NLC - там, часом, не правленный уже движок, как раз с отрезанными параметрами ?По тому как в норме это именно движком и делается.Чтобы скриптом - читать из костюма, и менять db.actor.power как надо.Формулу при этом лучше использовать вообще свою, поскольку движковые нормальный человек все равно не восстановит - они там странны весьма.Навскидку - stand_power из actor.ltx * power_restore_speed из костюма за тик, или что-то типа этого, но кто такой тик - неизвестно. Скорее всего он вообще меняется постоянно. upd: да, не может быть, что просто со знаком напутано ? Я вот тоже не помню, где там "+", а где "-". Изменено 12 Декабря 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 12 Декабря 2014 Забавно. При том, что power_loss работает вполне отчетливо. Ну и тем лучше - просто по нужным костюмам банально скриптом в апдейте изменяем power актору так, как нам нужно, а параметр в костюмах - банально, попугаи для вывода на экран. Даже конфиги читать не надо - нужную цифру сразу в скрипте прописываем. Это если надо именно восстановление. А если потерю - то прекрасно работает пара в конфиге без всякого скрипта. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 12 Декабря 2014 (изменено) Ну, как бы, в оригинале нет, но в любом моде уже есть подобный уродец (bind_stalker.script): if upd_time1 == nil then upd_time1 = time + 1000 elseif upd_time1 < time then upd_time1 = time + 1000 вот прямо следующей строкой и дописываем банально: db.actor.power = 0.1 это будет полное восстановление выносливости за 10 секунд. Чуть более продвинутый вариант, с проверкой костюма: local outfit = db.actor:item_in_slot( 6 ) if outfit and outfit:section() == "my_super_duper_outfit" then db.actor.power = 0.1 end Ну и т.д., по вкусу и что конкретно надо. Формулы - ффсад. Движок пусть свое сам считает, а мы просто тупо добавим, что хотим. 2 abramcumner: разве дельта, а не абсолютное значение ? Изменено 16 Декабря 2015 пользователем Dennis_Chikin 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 13 Декабря 2014 Поясняю: elseif upd_time1 < time then upd_time1 = time + 1000 -- это действия, производимые раз в секунду. уродец оно по тому, что как тот Бармалей пытается сделать все сразу, а потом еще такие же проверки обычно производятся в других местах. Вариант с * delta -- это действия, производимые каждый апдейт. Чем оно плохо - можно увидеть на примере работы acr*.script В общем, думайте сами, решайте сами... if db.actor.power < 0.99 then local outfit = db.actor:item_in_slot( 6 ) if outfit and outfit:section() == "my_super_duper_outfit" then db.actor.power = db.actor.power + 0.1 end end где - my_super_duper_outfit -- название "артефактного" костюма в конфиге, исполняемое раз в секунду - это действительно наиболее просто и наглядно. Но, кстати, в NLC должно быть где-то нечто подобное, которое на каждый чих этот самый db.actor.power уменьшает. И то же самое для всякого разного другого. Проще найти, и оторвать. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 13 Декабря 2014 (изменено) У меня здесь еще и опечатка. 8(Не acr, а arc. Это сам себе мод - контейнеры для артефактов, дневники контролеров и еще какие-то стимуляторы. В общем, плохо оно работает. Криво и глючно."И это единственно верный вариант для моделирования более мене реального поведения системы." - случайны интервалы от 20 до 70 ms, да еще их все учитывать и хранить ? Когда надо одно действие раз в n секунд ?Ландавшиц смотрит на этот пост с удивлением. upd: сдаюсь. Я не готов к дискуссии о вкусе фломастеров. Изменено 13 Декабря 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 14 Декабря 2014 (изменено) Интересно, только я вижу здесь странное (xr_meet.script): function Cmeet_manager:get_key_from_distance(t) local key for k,v in pairs(t) do if v.dist >= self.dist then key = k else return key end end return key endили ни кто сложной логики типа 40|something1, 20|something2, 10|something3 - никогда не писал, а потом не удивлялся результату ?Все всегда пишут 5|... , 10|... , 20|... ? Или в данном случае сортировка движком при заполнении таблицы все же срабатывает правильно ? 2 BlooderDen, да, просто я забыл за давностью лет: при чтении получаем текущее значение, а при записи - записанное суммируется с текущим. Повесить на выполнение, скажем, раз в пять секунд вывод в лог что-то типа log( "test", "actor.power = %s", actor.power ) actor.power = 0.1 log( "test", "actor.power > %s", actor.power ) - все будет вполне наглядно - вместо того, чтобы упало до 0.1 - второй раз будет то же значение, а после завершения текущего апдейта - добавится вот этот самый 0.1. Кстати, если хочется посмотреть, как влияют те же арты, или еще что - вешаем на раз в секунду, и получаем как раз сумму всего-всего за эту секунду. Весьма наглядно. Изменено 14 Декабря 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 19 Декабря 2014 Если уж в скриптовании, то в bind_stalker.script после if self.bCheckStart then ... _G.g_start_avi = true дописать self.object:set_actor_position( куда надо ) 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 21 Декабря 2014 (изменено) Вот та самая ссылка, которая в голосовалке зачем-то - в ей все и есть. str = pick_section( actor, npc, tt.buy_supplies ) if ( tt.current_buy_supplies ~= str ) or ( not tt.resuply_time ) or tt.resuply_time < game.get_game_time() then npc:buy_supplies( tt.config, str ) -- здесь все и удаляется. Кстати, поправил вчера вот как раз чтоб get_game_time() сравнивалось, а не глобальное. А ежели buy_supplies нету - оно до этого момента и не добирается. Ну и таки да, все полотна про 15700 костюмов с мигающими красным ПНВ все нормальные люди из всех конфигов посносили лет 5 назад, потому что по дефолту все прекрасно берется из system.ltx [trade] buy_price_factor_hostile = ; коэффициент покупки при goodwill = -100 buy_price_factor_friendly = ; коэффициент покупки при goodwill = 100 sell_price_factor_hostile = ; коэффициент покупки при goodwill = -100 sell_price_factor_friendly = ; коэффициент покупки при goodwill = 100 Изменено 21 Декабря 2014 пользователем Dennis_Chikin 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 2 Января 2015 Господа присяжные заседатели ! А не может ли кто-нибудь либо кинуть ссылко на статеечку, либо написать собственно эту самую статеечку про схемы, а конкретно вот про такую черную магию: evid_see_stuff = 6931 -- evid_near_stuff = evid_see_stuff + 1 -- evid_see_body = evid_see_stuff + 1 -- 2 -- evid_position_corrected = evid_see_stuff + 3 actid_reach_item = evid_see_stuff function add_to_binder( npc, ini, scheme, sect, st ) local manager = npc:motivation_action_manager() local prop_idlecombat = xr_evaluators_id.state_mgr + 3 local prop_contact = xr_evaluators_id.stohe_meet_base + 1 manager:add_evaluator( evid_see_stuff, ev_see_stuff( st, "ev_see_stuff" ) ) action = act_reach_item( "act_reach_item", st ) action:add_precondition( world_property( stalker_ids.property_alive, true ) ) action:add_precondition( world_property( stalker_ids.property_enemy, false ) ) action:add_precondition( world_property( stalker_ids.property_danger, false ) ) action:add_precondition( world_property( prop_contact, false ) ) action:add_precondition( world_property( xr_evaluators_id.sidor_wounded_base, false ) ) action:add_precondition( world_property( blowout_scheme.evid_anomaly, false ) ) action:add_precondition( world_property( blowout_scheme.evid_blowout, false ) ) action:add_precondition( world_property( evid_see_stuff, true ) ) -- action:add_precondition( world_property( evid_near_stuff, false ) ) action:add_precondition( world_property( prop_idlecombat, true ) ) -- action:add_effect( world_property( evid_near_stuff, true ) ) action:add_effect( world_property( evid_see_stuff, false ) ) manager:add_action( actid_reach_item, action ) action = manager:action( xr_actions_id.alife ) action:add_precondition( world_property( evid_see_stuff, false ) ) -- action = manager:action( stalker_ids.action_danger_planner ) -- action:add_precondition( world_property( evid_see_stuff, false ) ) end - ну, это я тут позакомментировал ненужного мне, поскольку переписано со сносом over 2/3 исходного, но собственно вопросы по черной магии: evid_see_stuff = 6931 -- откуда берется сия магическая цифра ? actid_reach_item = evid_see_stuff -- почему должна быть она же, а не какая другая. local prop_idlecombat = xr_evaluators_id.state_mgr + 3 -- для чего здесь и далее вот это local prop_contact = xr_evaluators_id.stohe_meet_base + 1 -- и откуда оно опять таки берется. Ну, то есть, интуитивно (и дальнейшими тестами) понятно, что первое - дабы не получилось анимации из анекдота про "до батареи одни уши доехали", а второе - чтобы разговор не обрывал, и актора не подвешивал. Но а по-русски это все как сказать ? И, опять же, по-русски - почему недостаточно просто action = manager:action( xr_actions_id.alife ) action:add_precondition( world_property( evid_see_stuff, false ) ) Наконец, самое интересное, это вот это магическое сочетание: action:add_effect( world_property( evid_see_stuff, false ) ) manager:add_action( actid_reach_item, action ) - где add_effect со значением false не понятен даже и интуитивно, хотя вполне нагляден, если и его закомментировать. Ну или в оригинале примерно ту же функцию выполняет эквилибристика с evid_near_stuff. Не, если я это сам начну расписывать - то даже и сам же потом не пойму. А кому-то, глядишь, могла бы и польза выйти. Да и себе бы сегодня день сэкономил на вспоминание "кто на ком стоял", если бы статеечка была. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 10 Января 2015 Чтобы было везде - везде и менять надо. И, да, изменения через пакет будут только после s/l. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 17 Января 2015 Ну, собственно, и tips и custom_static'и вполне годятся. В принципе же - старый бобрый "биорадарчик". Текст масштабировать смысла не вижу. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 18 Января 2015 "Заспавнить сидящим" - ни как. Только назначить логику kamp@, или написать что-то свое, принудительно отключающее любые другие схемы, и устанавливающее state_mgr.set_state( npc, "sit_ass" ) http://stalkerin.gameru.net/wiki/index.php?title=SoC._%D0%9B%D0%BE%D0%B3%D0%B8%D0%BA%D0%B0_NPC Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 1 Февраля 2015 На взятие - почему нет ? (Единственно что, надо иметь в виду, что при загрузке взятие отрабатывается для ВСЕХ предметов, и если их много - тогда будет ой.) С брониками и стволами нет, но есть, например, телепорты. При создании: tt = get_anomaly_data( obj ) cd = parse_custom_data( tt.custom ) cd.cd = { ["id"] = v } tt.custom = gen_custom_data( cd ) set_anomaly_data( tt, obj ) При входе в онлайн: local ini = self.object:spawn_ini() local n = ( ini and ini:section_exist( "cd" ) and ini:r_string( "cd", "id" ) ) or abort( "(%s):reload, invalid section [cd]", self.object:name() ) local id = self.object:id() self.teleport = n -- идентификатор для чтения параметров t_ids[n], t_spawn[id] = id, n В принципе, можно проще. Здесь сразу предполагается странное, поэтому еще добавлено разбор кастомдаты и ее преобразование обратно в строку. Если не нужно - можно сразу строкой и записать. Функции брать традиционно из амк, (ну или альтернативные ). Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 13 Февраля 2015 Возросшее в разы время говорит как раз о том, что экземпляров получается отнюдь не один. Далее остается понять, сколько же их нужно на самом деле. Во-первых. Во-вторых - нужно ли оно именно в глобальном пространстве (иногда тактически верно определить внутри модулей). Ну и, да, "простоты" не вижу. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 13 Февраля 2015 (изменено) Вот "с какого мода вырезать" - это точно не поможет. Тут надо определиться: что именно надо и для чего. Если нечто полномасштабно-коробочное - поиск по m_timers (несколько страниц назад). Если что-то одноразовое - то какое именно время нужно, и для чего. И, кстати, а нужно ли именно время ? Изменено 13 Февраля 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 665 Опубликовано 14 Февраля 2015 Тогда стартовый пост стоило бы как-то переформулировать, что-ли... Inventory_Utils_Operator = inv_system.Utils_Operator() -- вот он создался. В смысле, объект класса Utils_Operator. Ссылка на этот объект лежит в _G.Inventory_Utils_Operator. self.Utils_Operator = _G.Inventory_Utils_Operator -- теперь ссылку скопировали еще и в self.Utils_Operator а вот если self.Utils_Operator = inv_system.Utils_Operator() -- будет столько объектов, сколько раз сделаешь. P.S. Можешь в лицензии запретить персонально мне использовать лицензируемое в каком-либо виде. Буду вынужден делать свое, да. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение