Перейти к контенту

Скриптование


Svoboда

Рекомендуемые сообщения

Господа, нужна ваша помощь. Кто шарит в скриптах? Хочу сделать комментарии к сообщениям о смерти сталкеров( чтобы сами НПЦ комментировали чью-либо смерть). 

Вот функция, отвечающая за выдачу новости о смерти сталкера:

Скрытый текст

-- Погиб сталкер.
-- Собираем инфу о погибшем
-- Собираем инфу о виновнике смерти
-- Готовим сообщение
function on_stalker_death(victim_, killer_)
 local rnd = math.random
 if (victim_ == nil) then
  return
 end
 local m_killer = ""
 local m_killer_s = ""
 local m_victim = ""
 local victim
 if (isGameObject(victim_)) then
  victim = victim_
 else
  victim = get_obj(victim_.id)
 end
 local killer
 local m_name  = get_npc_name(victim)
 m_victim = format_death_stalker_corpse(victim)
 local m_level = get_level_name(get_object_levelname(victim))
 if (killer_) then
  if (isGameObject(killer_)) then
   killer = killer_
  else
   killer = get_obj(killer_.id)
  end
  if (IAmAMonster[killer:clsid()]) then
   m_killer = format_death_by_monster(killer)
   m_killer_str = get_monster_name(killer, 2)
  elseif (IsAnomaly(killer)) then
   m_killer = format_death_by_anomaly(killer)
   m_killer_str = get_anomaly_name(killer, 1)
  elseif (IsNpcStalker(killer)) then
   local m_o_weapon = get_npc_weapon(killer)
   local m_s_weapon = ""
   if (m_o_weapon) then
    m_s_weapon = get_weapon_type(m_o_weapon)
    if (m_s_weapon < 5) then m_killer_str = "пулевое ранение" end
    if (m_s_weapon == 6) then m_killer_str = "нож" end
    if (m_s_weapon == 8) then m_killer_str = "ожоги" end
    if (m_s_weapon == 7 or m_s_weapon == 5) then m_killer_str = "граната" end
   end
   if (IsNpcActor(killer)) then
    add_killed_by_actor(victim) -- Отметим, что это ГГ постарался.
   end      
   m_killer = format_death_by_stalker(killer)
  elseif (IsNpcOther(killer)) then
   local m_o_weapon2 = get_npc_weapon(killer)
   local m_s_weapon2 = ""
   if (m_o_weapon2) then
    m_s_weapon2 = get_weapon_type(m_o_weapon2)
    if (m_s_weapon2 < 5) then m_killer_str = "пулевое ранение" end
    if (m_s_weapon2 == 6) then m_killer_str = "нож" end
    if (m_s_weapon == 8) then m_killer_str = "ожоги" end
    if (m_s_weapon2 == 7 or m_s_weapon2 == 5) then m_killer_str = "граната" end
   end
   m_killer = format_death_by_stalker(killer)
  else
   m_killer_str = "причина смерти - неизвестна"
   m_killer = ""
   if _debug == true then mylog("On stalker death - unknown killer. "..killer:name().." clsid="..get_clsid(killer)) end
  end
 end
 if (m_killer_str==nil or m_killer_str=="") then m_killer_str = "причина смерти - неизвестна" end
 local m_string = m_name..". "..m_level..", "..m_killer_str.."."
  do_news(m_string, "Погиб сталкер:", rnd(timer_stalker_death, timer_stalker_death * 3), 10, "death", nil, 1)   --------оригинальная строчка вывода сообщения на экран


  amk.send_tip("ТЕКСТ КОММЕНТАРИЯ НПЦ",  "ИМЯ НПЦ ", time, show time, "death(иконка)")         ---------этой строчкой рандомные НПЦ должны оставлять комментарии

  end

end
  

 


Суть проблемы вот в чем: строчка Do_News - тут прописан хитрый механизм, чтобы не засорять нам экран сообщениями о смертях, когда мы убили разом целую группу сталкеров (гранатой, например). Поэтому если мы разом убьем сразу 10 человек, придет только одно сообщение о смерти какого-нибудь из этих жмуриков..  Зато тут же через  amk.send_tip покажутся сразу 10 сообщений с комментариями. 

И вот тут мне нужна ваша помощь, скриптеры. Помогите как-нибудь реализовать такой механизм, чтобы либо:  1) Комментарий (amk.send_tip) вызывался бы только после вывода сообщения (do_news) о смерти НПЦ на экран (сделать какую-то зависимость, не знаю), либо 2) тоже сделать "антиспам", чтобы на 10 практически одновременных сообщений о смерти сталкеров (do_news) отобразился бы только один комментарий (amk.send_tip).

Есть какие-нибудь идеи?

 

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

Господа, доброго времени. Прошу вашей подсказки. 

Смотрите. Имеем интересный диалог, в котором мы предлагаем случайному НПС распить водку. Водку в инвентаре имеем. Функция проверила, что водка у нас есть и разрешила с НПС нам ее распить (появилась соответствующая ветка в диалоге с НПС). И вот тут я хочу через диалог передать водку НПС и заставить его ее выпить. Через функцию водку передал, а вот как заставить его выпить водку? Суть в том, что просто уничтожить водку - не подойдет. Имеется модификация, которая заставит НПС после выпитой водки сначала отрубиться спать, а потом чувствовать жуткое похмелье. Так вот, как заставить НПС съесть водку? А вдруг можно как-то заставить скриптово НПС еще и анимацию проиграть? Как в Зов Припяти, например, когда с нами бородач там водку распивал. Есть идеи, хорошие мои?

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ребят, все еще прошу помощи. Не получается заставить НПС "съесть" водку через диалог. 

Имеем функцию, которая вызывается через диалог:

Скрытый текст

function drink_vodka()   --в диалоге вызывается функция, если:

      if new_dialog.item_much("vodka" ,1) ~= false   --..если в инвентаре имеем хотя бы одну водку
      then  
                 dialogs.relocate_item_section(second_speaker, "vodka", "out")  --отдаем одну бутылочку горючки НПС через диалог (работает, у НПС появляется в инвентаре моя водка, а у меня пропадает)
                 db.actor:eat(db.actor:object("vodka"))  --сами выпиваем водочку (РАБОТАЕТ, мы пьянеем и экран покачивается)
                 self.npc:eat(self.npc:object("vodka"))   --НПС должен выпить водку (не работает)
     end

end

В итоге игра грузится, начинаю диалог с НПС. Проверка на наличие водки проходит и появляется строчка с предложением к НПС распить водочку. Жмем и тут же вылет:

Скрытый текст

....... "attempt to index global 'self' (a nil value)"

Есть идеи, как таки заставить НПС съесть водку и пофиксить скрипт? :(

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

@AndreySol А без self просто выкидывает с ошибкой на этот файл.script

А заставить его съесть водку хочу потому что подключен АИ от МОНка, где есть схема "пьянчуга", вроде как НПС должен страдать похмельем, или же вообще упасть и отрубиться. Я копался в этом скрипте и вроде как там написано что если НПС ест водку, то включается схема пьянчуги. 

А анимацию его через диалог никак не заставить проигрывать, да?

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

(изменено)

Да, ты прав. Просто вылет без конкретной ошибки. Слушай, а если вначале создать условную дополнительную функцию (любое название, допустим "РАЗДВАТРИ") распития водки НПСёй, а потом, когда будет вызываться наша главная функция drink_vodka, то в ней будет:

1) передача водки

2) распитие актором другой водки (если водки в инвентаре нет, то актор просто ее не пьет)

3) вызов нашей только что созданной предыдущей функции "РАЗДВАТРИ", где описан процесс распития водки НПСёй

Так может сработать? 

Блин, надеюсь ты меня понял)

Изменено пользователем _Sk8_AsTeR_

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

И еще возник вопрос уже по другой теме.

Модернизирую "динамические сообщения". Заставляю НПС именно чатиться друг с другом по разным темам. Получается довольно интересно. То есть могут быть по 3-4 сообщения об одной теме. 

Вот только имена у нпс, отправивших сообщение - просто рандомные имя и фамилия из файлика. То есть отправляют сообщения несуществующие нпс. Отсюда вопрос: А можно сделать так, чтобы отправители сообщения были реальными рандомными нпс? Пытался что-то выдернуть из файла "News_main" из сообщений про торговлю пушками от случайных нпс, но не вышло. Отправитель не отображается, просто пустота вместо имени и фамилии. Или хотя бы есть способ разные рандомные иконки персонажей прикрутить к сообщениям? Хоть как-то сделать этот процесс общения по сталкерской сети немного реалистичнее...

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

@BossBoroda выборка имен и прозвищ и так идет из АМКшной таблицы. Но они рандомно сочитабтся друг с другом. А я имею в виду чтобы реально скществующие НПС были авторами сообщений. Повстречали мв под мостом Андрей Штврь сталкера, и вот чтобы этот Андрей Штырь, например, и был автором сообщения

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

@AndreySol

Цитата

Сделать вместо файла, как я понял, из которого идет выборка имен и погонял, табличку, которую заполнять именами и прозвищами реальных неписей. Затем выборку делать уже из этой таблички.

Прости за долгий ответ и за мою приставучесть. Я понял о чем ты только сейчас. когда перечитал переписку. Сделать руками табличку существующих ИМЯ+ПРОЗВИЩЕ нпсей. Но в таком случае получается, что автором отправленных сообщений является великий рандом, случайно выдергивая ИМЯ+ПРОЗВИЩА из таблички. Как вариант... Но все равно немного не то. 

А вот я имел в виду, чтобы игра сама подставляла имя+прозвища реальных существующих нпс. Я проштудировал насклько мог скрипт news_main соляночный. Там существующие неписи спамят в чат о событиях. Там все ясно. Если в радиусе от нпс было событие, он спамит. Однако была функция, описывающая спам от нпс, которые кидали предложения о продаже в чат. То есть рядом с ними не было никаких событий. То есть игра сама как-то выбирает рандомно СУЩЕСТВУЮЩЕГО нпс и отправляет от его имени сообщение. Пробовал перебрать его функцию и из нее слепить свою, но вместо имени и прозвища была пустота. То есть в теории как-то сделать можно, но моих мозгов на это не хватает. :(

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

(изменено)

Господа, выручайте!

Подскажите, знатоки, как через функцию get_npc_name в скрипте news_main, например, вернуть имя абсолютно любого рандомного СУЩЕСТИВУЮЩЕГО нпс? Онлайнового или оффлайнового...

Сама функция:

Скрытый текст

function get_npc_name(obj)
 local m_s_name = ""
 if (obj) then
  if (isGameObject(obj)) then
   if (obj.character_name) then
    m_s_name = obj:character_name()
   end
  else
   local ob = get_obj(obj.id)
   if (ob and ob.character_name) then
    m_s_name = ob:character_name()
   else
    if (amk and amk.read_stalker_params and IsNpcStalker(obj)) then
     local tbl = amk.read_stalker_params(obj)
     if(tbl and tbl.charname) then
      m_s_name = tbl.charname
     end
    end
   end
  end
 end
 if (m_s_name == nil) then
  m_s_name = ""
 end
 if (m_s_name == "") then
  --m_s_name = get_npc_community(obj)
 end
 return m_s_name
end

Посмотрел много примеров, как имена возвращаются из этой функции для разных других функций. Это все касается сообщений от НПС в чат. Торговля, увидели кого-то, увидели как мы сделали что-то и тдтп. Везде идет обращение к этой функции. 

У меня была идея сделать так, чтобы через эту функцию имя возвращалось для любого нпс, который находится от нас на определенном радиусе. Но по идее это будет касаться только онлайновых НПС, да и то у меня имена так и не возвращались. Вместо отправителя на экране была пустота. Приходило пустое сообщение ни от кого. Есть идеи, хорошие мои?

Изменено пользователем _Sk8_AsTeR_

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

В ‎14‎.‎09‎.‎2017 в 10:53, naxac сказал:

@_Sk8_AsTeR_, тебе же написали:

Только таблицу заполняй не неписями, а их именами, получить которые можно из их нет-пакетов.

Черт, да, понял. Блин, это будет наверное слишком сложно для моих мозгов, тк я только погружаюсь в пучину скриптования. А жаль, вышла бы неплохая фишка. Ладно, спасибо 

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

(изменено)

Господа, выручайте. Наткнулся на самую настоящую для моих мозгов аномалию! В общем, написал я небольшой таймер

Скрытый текст
local time_news = 10
local time_m = 1
local time_h = time_m * 60
local time_d = time_h * 24
local rnd = math.random

function time_update_spam()
local iTimer = amk.game_minutes()
      iTimer = amk.game_minutes() + math.random(time_h, time_d) --как только грузанулись взвелся таймер, рандом от часа до дня ИГРОВОГО
      -- далее функция ожидания истечения таймера--
      local function check_timer()
         return amk.game_minutes() > iTimer
      end
      -- ставим её на апдейт
      level.add_call(check_timer, action_timer)
end
 
function action_timer()
   if time_news < amk.game_minutes() then  
     time_news = amk.game_minutes() + rnd(time_d) -- время через которое будет вызываться сообщение
 news_main.do_RANDOM_NEWS()  --функция, которую мне нужно вызывать с некоторым промежутком времени
-- amk.send_tip( "заголовок", "таймер истёк", 1, 15, "common_channel")
    end
end

Сама функция таймера "time_update_spam()"у меня вызывается из скрипта bind_stalker - функции actor_binder:update(delta)

И все великолепно работает, таймер исправно запускает функции через отведённое время. Но вот проблема. Падает фпс! Как только загрузился - от 60 до 100 фпс. Через 5 минут реального времени всегда фпс падает до 10. Именно из-за таймера. Или функции, которую он вызывает, не знаю. Стоит только закомментить в Бинд_Сталкере строчку с вызовом функции таймера и перезагрузить игру как фпс снова возвращается на былые значения. Что это может быть?

Изменено пользователем Kirgudu

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

@dsh @Faustle Спасибо за подсказки. Следуя вашим советам столкнулся с новой проблемой: таймер между вызовом моей функции работает. Однако первичный вызов функции происходит без задержки, моментально. А это мне не подходит. То есть как только я гурзанул сейв сразу вызывается моя функция, и только после этого заводится таймер. Как можно вызвать задержку на выполнение ф-ции?

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

(изменено)

В продолжение  своей проблемы

Исходя из информации, полученной выше от ребят, получается мы имеем вызов моей функции action_timer() из bind_stalker из ф-ции actor_binder:update(delta). Значит моя ф-ция автоматически обновляется. Тогда вопрос, что я делаю не так?

Скрытый текст

local time_news = 0
local iTimer = 0

function action_timer()
time_news = amk.game_minutes() + 2
   if time_news < amk.game_minutes() then  
   news_main.do_RANDOM_NEWS()
    end 
end

Ведь по идее, исходя из это, мой скрипт должен работать следующим образом: объявленной переменной time_news присваивается значение - игровое время + 2 минуты. И если эта переменная меньше чем игровое время в данный момент, то выполняется другая основная моя ф-ция do_RANDOM_NEWS(). И того выходит, что после загрузки сейва через 2 минуты игрового времени должна непрерывно начать постоянно вызываться моя основная ф-ция do_RANDOM_NEWS(), но этого не происходит. Оказывается почему-то что всегда переменная time_news перманентно больше игрового времени в данный момент. Как так?

 

Изменено пользователем _Sk8_AsTeR_

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

@dsh благодарю! Заучит логично, да! Приду домой и попробую сразу!  

@_Val_ апдейт Бинд_Сталкерский начинает крутиться только как загрузка завершится и ты в зоне окажешься. Причем с задержкой в доли секунды даже :)

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

Господа, а никто не реализовывал такую вещь, чтобы НПС стреляли реальными патронами из инвентаря? То есть нет патронов - нечем стрелять НПСишке. Прошу прощения у модеров, если не в ту ветку строчу. 

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

2 часа назад, Rietmon сказал:

Хай, пиплы. Возникла проблема с логикой. Как правильно сделать, что-бы НПС становлися враждебным при наличии поршня + переходил на другую схему логики? У меня получилось так:
 


[logic]
active = walker@stay_at_position
danger = danger_ignore

[danger_ignore]
ignore_distance = 5

[walker@stay_at_position]
path_walk = jup_zubr_kvest2_stay_at_position_walk
path_look = jup_zubr_kvest2_stay_at_position_look
corpse_detection_enabled = false
gather_items_enabled = false
help_wounded_enabled = false
on_info = {+zamok_otkaz_ot_oplati} walker@logic2 %=actor_enemy%

[walker@logic2]
corpse_detection_enabled = false
gather_items_enabled = false
help_wounded_enabled = false

Но в итоге получаю это: 
 


[error]Expression    : !m_error_code
[error]Function      : raii_guard::~raii_guard
[error]File          : ..\xrServerEntities\script_storage.cpp
[error]Line          : 748
[error]Description   : ...k.e.r the stumbling block\gamedata\scripts\_g.script:479: bad argument #2 to 'format' (string expected, got nil)

Помогите, я уже 3 дня ломаю голову, как сделать этот чертов момент(через сквад нельзя - спавн нпс идет не через него, а заменить тоже нельзя - сама задумка сюжета не получится).

Судя по логу ошибка расшифровывается следующим образом: в _g.script в строке 479 конфликтует второй аргумент функции (я полагаю), в этом моменте скрипт ожидает строчное значение,  а на деле получает пустое(nil)

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

(изменено)

Господа, подскажите пожалуйста по поводу таймера. Сделал простенький таймер, корни которого тянутся из bind_stalker ( ф-ция: actor_binder:update(delta)). По истечению таймера вызывается функция.

Простенький таймер исправно работает, но отчет начинается всегда только с загрузки сейва, или загрузки локации. А мне нужно, чтобы отчет начинался от предыдущего вызова функции. То есть что я имею в виду (объясню пошагово):
 

Скрытый текст

 

1) Загрузились, начался таймер (пусть будет 10 игровых минут). По истечению таймера (условно 10 игровых минут) вызвалась функция. 

2) Далее в игре проходит 8 минут, я сохраняюсь и перезагружаю сейв (или вообще перезапускаю игру).

3) После загрузки сейва нужно чтобы таймер продолжал с 8-ой минуты отчет и на 10-ой снова вызвал функцию

 

Подскажите, в какую сторону копать? Не подобный ли таймер реализован АМК? Имею в виду динамические новости. Там вроде именно так они работают...

Изменено пользователем _Sk8_AsTeR_

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

Господа, выручайте :(

При первом переходе на Неразведанную Землю ловлю вылет на этапе загрузке уровня:

Скрытый текст

Expression    : fatal error
Function      : CInifile::r_section
File          : E:\stalker\sources\trunk\xrCore\Xr_ini.cpp
Line          : 342
Description   : <no expression>
Arguments     : Can't open section 'aver_musics'

Куда копать, подскажите пожалуйста

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Graff46

Посмотрел лог успешной загрузки другого уровня. Похоже что это грузятся звуки уровня.

На успешном логе проходит эта стадия успешно: Loading music tracks from 'marsh_musics'  (болота вроде грузил, где Чистое Небо тусуется)

А при загрузке Неразв. Земли тут загрузка спотыкается:  Loading music tracks from 'aver_musics'...    FATAL ERROR

Где-то нужно смотреть конфиги ззвуков на отсутствие соответствующей секции, если я все верно понял. Но вот где...

Поделиться этим сообщением


Ссылка на сообщение
Поделиться на других сайтах

  • Недавно просматривали   0 пользователей

    Ни один зарегистрированный пользователь не просматривает эту страницу.

AMK-Team.ru

×
×
  • Создать...