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

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

Тема для обсуждения скриптов всего и всех в серии игр STALKER.


Задавая вопрос (!):
1. Внимательно изучите суть вопроса. Вопрос должен соответствовать выбранной Вами темы. Это поможет сохранить порядок и читабельность темы, а также облегчит поиск и понимание сего;
2. Изучите то, что уже есть в теме (пролистайте "руками", воспользуйтесь поиском на форуме);
3. Изучите информацию которая может вам помочь:

 
 

Stalkerin. Там есть много хороших статей касательно данной темы.
Уроки по модостроению. Есть рабочие примеры готовых скриптов различного назначения.

 

Справочное руководство по языку Lua 5.1
https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual/ru
Справочник по функциям и классам. Собрано много информации по функциям и классам, не всем, но по основные сведения предоставлены.

4. Дабы не превращать обсуждение в "кашу" разной информативной направленности, задавайте несколько вопросов по порядку (в разных постах) после того, как получите ответ на предыдущий вопрос;
5. "Спасибо" и тому подобное - будьте так любезны в ПМ. Если не любите писать в ПМ, в конце вопроса напишите фразу: "Заранее спасибо!" - или что-то в этом духе;
6. ПОЖАЛУЙСТА! Указывайте, для какой игры Вам необходима информация (ТЧ, ЧН, ЗП), если стоит мод - укажите название мода;
7. Если Вы что-то сделали и результат не такой, какой Вами задумывался, то, пожалуйста, приводите коды которые Вы изменяли/писали целиком! Это поможет другим правильно ответить на Ваш вопрос, а также оградит Вас от лишней писанины.
8. Оформляйте сообщение. Пользуйтесь тегами для того, чтобы отделить код от текста. Пишите грамотно - ПОЛЬЗУЙТЕСЬ ЗНАКАМИ ПРЕПИНАНИЯ.
9. И помните: «Правильно заданный вопрос – половина ответа».

 

Какие вопросы следует задавать, а какие нет...

 

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

 

Вопросы которые будут удалятся, следовательно их задавать не нужно:
-- Где находится та или иная функция?
Для ответа используем поиск по словам среди файлов оригинальной игры или мода, если объект поиска относится к нему, при помощью программы, которая Вам наиболее симпатизирует;
-- Как сделать что-то/то-то?
С подобными вопросами, либо в "ковырялки", где Вам вероятнее всего так же не ответят, либо выдвигаем мысли, подкреплённые теорией, практикой (идеальный вариант) и здравым рассудком;
-- Вопросы со смыслом: "сделайте", "совместите" и подобными глаголами повелительного наклонения.
-- К тому же удалению будут подвергаться вопросы, в которых масштабно не используются теги, для отделения кода и цитат от основного текста, а также не вписан в спойлер код размером превышающие семь строк.
Ответ на возможно возникший вопрос: В какую тему можно обратиться по поводу логики и спавна объектов?
В тему "ковырялок" соответствующей версии игры, для которой Вы задаёте вопрос.

И последнее: очень рекомендовано к прочтению Правила форума
 


  • Спасибо 1
  • Полезно 2
Ссылка на комментарий

Подскажите в чем проблема? Имею такую функцию:

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

function spawn_meat(victim, who)
    local meat_position = victim:position()
    local meat_direction = victim:direction()
    meat_direction = vector_rotate_y(meat_direction, math.random(-180, 180))
    meat_position.x = meat_position.x + meat_direction.x * random_float(0.5, 0.7)
    meat_position.y = meat_position.y + meat_direction.y + 1
    meat_position.z = meat_position.z + meat_direction.z * random_float(0.5, 0.7)

    local monster_meat = monster_to_meat[victim:clsid()]
    for i = 1, math.random(1,3) do
    alife():create(monster_meat, meat_position, victim:level_vertex_id(), victim:game_vertex_id())
end
end

 

Спавн itema по кругу трупа мутантов. Но они спавняться в одно стопке. в чем проблема? https://disk.yandex.ru/i/-miHtOu9MKTVhA

 

Изменено пользователем Colder
Ссылка на комментарий
4 часа назад, Colder сказал:

 for i = 1, math.random(1,3) do

эту строчку перенеси в самое начало функции

  • Спасибо 1
Ссылка на комментарий

Как правильно прочитат рандомно название оружия или где то можно подсмотреть?

Пробовал так:

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

local weapon_classes  = {
    [clsid.wpn_svu] = true,
    [clsid.wpn_svu_s] = true,
    [clsid.wpn_usp45] = true,
    [clsid.wpn_usp45_s] = true,
    [clsid.wpn_val] = true,
    [clsid.wpn_val_s] = true,
    [clsid.wpn_vintorez] = true,
    [clsid.wpn_vintorez_s] = true,
    [clsid.wpn_walther] = true,
    [clsid.wpn_walther_s] = true
}

function irWeapon(object, class_id)
    local id = class_id or get_clsid(object)
    return id and weapon_classes[id]
end

function show_news()
    if irWeapon(item) then
    local name = system_ini():r_string(item:section(), "inv_name")
    local n = name[math.random(#name)]
    local ww = gts(n)

    local news_text = "%c[ui_gray_1]".. ww
    db.actor:give_game_news(news_text, "ui\\cop\\ui_cop_iconstotal", Frect():set(415,0,83,47), 0, 5000)
end
end

но ничего не приходит.

Ссылка на комментарий
50 минут назад, Colder сказал:

Не помогло. 

Ладно... Пойдем длинным путём...

В функции show_news переменная item откуда берётся?

S.T.A.L.K.E.R. CoP Objects (upd 15.11.24)

Ссылка на комментарий
2 часа назад, Colder сказал:

Как правильно прочитат рандомно название оружия

Вообще не понял...

Может, стоит для начала рандомно  определить оружие?

Здесь могла быть ваша реклама.

Ссылка на комментарий
20 минут назад, mole venomous сказал:

Может, стоит для начала

Адекватно сформулировать вопрос :)

Чтобы хотя бы было понятно, чего хочется достичь, и откуда что берется на данный момент.

3 часа назад, Colder сказал:

local n = name[math.random(#name)]
    local ww = gts(n)

Я что-то не припоминаю чтобы для строк в Lua применялся оператор #. Что тут должно получиться, одна рандомная буква из названия?

Загадочная функция gts не приведена.

Судя по тому что оно не вылетает на #строка, подозреваю что функция show_news с заключенным в ней блоком вообще не вызывается.

  • Согласен 3

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий
4 hours ago, Zander_driver said:

чтобы для строк в Lua применялся оператор #

Длина строки успешно читается… Есть какие-то особые случаи?

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Ссылка на комментарий
7 часов назад, Norman Eisenherz сказал:

особые случаи?

string.len

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

Оператор #, кстати, вполне успешно вернёт длину строки, но это ничему не поможет.

Предположим, что загадочная функция gts - это game.translate_string. Предположим даже, что функция show_news действительно вызывается, но тогда непонятно, как в неё передаётся переменная item, ведь show_news объявлена за пределами on_trade, а область видимости переменной item - внутри on_trade. Скорее всего, как писали выше, передавать item в функцию таки необходимо.
Но и это ещё не всё.

local name = system_ini():r_string(item:section(), "inv_name") - здесь переменной name присвоится строка. Одна строка.

#name отработает и даст длину, math.random(#name) - случайный индекс в пределах длины строки.
Однако name[math.random(#name)] вернёт nil, поскольку получить один символ из строки посредством обращения к индексу в Lua нельзя - у символов в строках просто нет индекса. Для этого необходимо использовать функцию string.sub.

Но даже если бы удалось получить символ, то после применения загадочной local ww = gts(n) в переменную ww попадёт ровно тот же символ без всякого перевода. Ибо вряд ли в xml с текстами найдутся записи, идентификаторами которых служат одиночные символы латинского алфавита...

  • Нравится 2
  • Согласен 1
Ссылка на комментарий

@Kirgudu 

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

local gts = game.translate_string

local weapon_classes  = {
    [clsid.wpn_svu] = true,
    [clsid.wpn_svu_s] = true,
    [clsid.wpn_usp45] = true,
    [clsid.wpn_usp45_s] = true,
    [clsid.wpn_val] = true,
    [clsid.wpn_val_s] = true,
    [clsid.wpn_vintorez] = true,
    [clsid.wpn_vintorez_s] = true,
    [clsid.wpn_walther] = true,
    [clsid.wpn_walther_s] = true
}

function irWeapon(object, class_id)
    local id = class_id or get_clsid(object)
    return id and weapon_classes[id]
end

 

function show_news(item)
    if irWeapon(item) then
    local name = system_ini():r_string(item:section(), "inv_name")
    local n = name[math.random(#name)]
    local ww = gts(n)

    local news_text = "%c[ui_gray_1]".. ww
    db.actor:give_game_news(news_text, "ui\\cop\\ui_cop_iconstotal", Frect():set(415,0,83,47), 0, 5000)
end
end

 

Вызываю с ui_main_menu по кнопке

 

Можно было сделать так :

 

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

function show_news()
    local where_trade = txr_utils.collect_translations("st_dyn_news_lvl_",true)
    if (not where_trade) then
    return false
end
    local wt = where_trade[math.random(#where_trade)]
    local news_text = "%c[ui_gray_1]".. wt
    db.actor:give_game_news(news_text, "ui\\cop\\ui_cop_iconstotal", Frect():set(415,0,83,47), 0, 5000)
end

 

txr_utils:

 

local cache_translated = {}
local cache_untranslated = {}
local string_find = string.find

 

function collect_translations(st, is_translated)
    if is_translated and cache_translated[st] then
    return cache_translated[st]
    elseif cache_untranslated[st] then
    return cache_untranslated[st]
end
    local string_count = 1
    local tr_t = {}
    while true do 
    local tr_s = game.translate_string(st .. string_count)
    if (tr_s == st .. string_count) then
    break
    else
    if is_translated then
    tr_t[#tr_t + 1] = tr_s
    else
    tr_t[#tr_t + 1] = st .. tostring(string_count)
end
end
    string_count = string_count + 1
end
    if (#tr_t == 0) then
    if (not string_find(st,"st_msg")) then
    printf("! WARNING: collect_translations | strings of (%s) don't exist!", st)
end
    return false
end
    if is_translated then
    cache_translated[st] = tr_t
    else
    cache_untranslated[st] = tr_t
end
    return tr_t
end

 

Но это не решает проблему, ведь он будет читать строку в виде ...._1, ..._2 и т.д. А мне нужны имена оружий.

 

Ну не писать же длинющий список:

 

local where_trade = {
    "ПМ",
    "ПБ",
    и т.д
}

Я так понимаю это не реализовать?

 

Изменено пользователем Colder
Ссылка на комментарий

@Colder  Вот поэтому и стоит для начала сделать то, о чём писали выше:

19 часов назад, mole venomous сказал:

Вообще не понял...

Может, стоит для начала рандомно  определить оружие?

Нужно получить список имён оружия и вывести его в новости. Какого оружия, где? В слоте? В инвентаре? На уровне? Вообще любого в игре? Передаваемого покупателю/продавцу (если отталкиваться от on_trade? Если берёшь в работу один единственный предмет, который передаётся в параметр item функции on_trade, то о каких множественных строках, перебор которых ты хочешь сделать, может идти речь? И т. д.
Цель непонятна, условия непонятны, а гадать, что именно требуется сделать, - неблагодарное занятие.

Изменено пользователем Kirgudu
  • Согласен 2
Ссылка на комментарий

Перебирает все предметы в игре (на всех локациях), помещает уникальные записи оружия в таблицу, затем выводит в новость случайное название из этой таблицы:

local weapon_names, weapon_sections, cnt, sini, al = {}, {}, 0, system_ini(), alife()
for i=1, 65535 do
	local obj = al:object(i)
	if obj and isWeapon(obj) then
		local section = obj.section_name and obj:section_name()
		if section and (not weapon_names[section]) and sini:section_exist(section) and sini:line_exist(section, "inv_name") then
			local name = sini:r_string(section, "inv_name")
			weapon_names[section] = name
			table.insert(weapon_sections, section)
			cnt = cnt + 1
		end
	end
end
if cnt > 0 then
	local news_text = "%c[ui_gray_1]"..game.translate_string(weapon_names[weapon_sections[math.random(cnt)]])
	db.actor:give_game_news(news_text, "ui\\cop\\ui_cop_iconstotal", Frect():set(415,0,83,47), 0, 5000)
end

Вот только затратная это штука благодаря перебору.

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

Изменено пользователем Kirgudu
  • Спасибо 1
  • Нравится 1
Ссылка на комментарий
10 hours ago, Kirgudu said:

пройтись по всем конфигам и вычитать из них секции с оружием

Сходная задача: надо получить все входящие секции из конфига [weapons.ltx]. Перебор через line_count + r_line требует указания общей секции "list", которой в этом конфиге нет. Версия игры – ТЧ 1.0006, библиотека io. недоступна. Какое есть решение?

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

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

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