Главная | Регистрация | Вход | Приветствую Вас | Гость| RSS















Меню
Реклама
Категории раздела
Работа со скриптами [32]
Самые разные полезные статьи по скриптам игры S.T.A.L.K.E.R
Работа с конфигами [13]
Всякие полезные материалы по работе со Сталкером ТЧ.
Базовые знания [6]
Основы для тех кто хочет заниматься модами.
Для тех кто чуть больше чем новичок :) [7]
Работа с ACDC, all.spawn , скрипты...
SDK [3]
Все о работе в официальном SDK.
Прохождения модов ТЧ. [21]
Здесь выкладываем различные прохождения кучи различных модов для ТЧ.
Свежий хабар






Главная » Статьи » Тени Чернобыля » Работа со скриптами

Скриптинг для новичков


Скриптование для НОВИЧКОВ.

Скриптинг


Я не профессионал, я не программист, я не изучал официальную справку по Lua, я не считаю себя гением и еще кем-либо.
В данном топе вы найдете готовые, самые используемые скриптовые функции, начальные сведения по скриптованию, научитесь писать примитивные скрипты(хотя их такими не назовешь), но я не смогу передать вам мой образ мышления и способность находить ответы на многие вопросы самому методом общего анализа...

(Данный материал я считаю своей интеллектуальной собственностью, если вы хотите опубликовать его еще где-то, то обязательно указывайте автора(да и пора бы уже научиться всегда указывать авторов,даже без требования) и не так: "ой забыл", "где-то видел", "какой-то чувак", а ник. Если вам понравился материал, можете и ссылку на данный форум скинуть(замаскировав под гиперссылку с текстом), я буду только благодарен.)



Урок первый. Что такое срипт?


1. Все файлы скрипты находятся в папке gamedata\scrips .
2. Файл скрипта - это текстовый файл имеющий расширение .script .
3. В С.Т.А.Л.К.Е.Р используется немного изменённый скриптовый язык Lua 5.1 .
4. Для редактирования скриптов я советую NotePad c++, данная программа имеет подсветку синтаксиса для многих языков, в том числе и для Lua. Чтобы активировать подсветку нажмите клините Стиль - Lua .
5. Чтобы закоментировать строку (код игры не будет ёё читать) , необходимо перед строкой поставить -- .
Если вы хотите закоментировать кусок (много строк) то --[[ .... ]] , ваш текст будет закоментирован.

Начнём уроки.
1)Создадим свой my.scripts и поместим его в папку scrips . Откроем с помощью НотПада и настроим подсветку.
2) Внутри файла-скрипта должны содержаться только КОД скрипта и ваши ЗАКОМЕНТИРОВАННЫе пометки. Если будет лишний текст, т.е какие-то знаки и слова, то будет вылет на этот скрипт. Так как код игры полностью собирает весь скрипт в стек и выбирает только то, что вы задали, но если будет мусор, то игра не воспримет код.
3)Архитектур. Для создания функций нужны лишь знания синтаксиса и игровые методы и глобальные функции(которые записаны в движке) можете почитать lua_help.scrip , но я советую посетить тему на АМК . Там собраны все методы, классы и полное их описание.
4) Функция. Это то, что будет делать игра.

Любая функция начинается со слов

function my_function()
...
end

И заканчивается тегом end. Этот тег означает конец функции, сравнения, он закрывающий и обязателен. Я советую при составлении функций , чтобы не забыть чего-нибудь, писать скелет извне, т.е сначала функция, потом закрывающий тег, и по нарастающей во внутрь.
() -Обязательный элемент. Позже расскажу как передавать переменные через этот тег.Между окончание функции и этим тегом ПРОБЕЛА НЕТ.

Обращаю внимание, что все функции вызываются из других скриптов. Допустим нам из одного скрипта, нужно вызвать(запустить функцию в другом) для этого мы пишем
название скрипта. название функции в скрипте(парметр если есть)
my.my_function()

Объявляем перменные и глобальные.

Чтобы объявить какой-либо элемент для функции локальным используется тег local
local helth = db.actor.helth
Т.е мы расшифровали helth , и показали , что это значение db.actor.helth.
Если вы хотите вставить слово или свой текст нужно заключить слово в кавычки.
local helth = "Уровень здоровья."
Если вы хотите вставить слово с кавычками или свой текст нужно сделать так:
local helth = "\"Уровень здоровья."\"
Чтобы объявить глобальну нужно всего лишь сделать так
helth = db.actor.helth

Глобальные можно объявлять вначале скрипта и она будет сохранятся в коде, в памяти процесса (если я правильно понял)
Переменная объявляется только перед функцией и логическими выражениями, где используется переменная и её использует только та функция, перед которой она объявляется (На пальцах перед строкой с вашей функцией). Т.е елси функция простая без логических решений(if, elseif, for и.т.д) То ставим перед функцией, если же есть переменная, которая находится в теле такого логического решения, то она ставится строго перед этим логическим решением!

local helth = db.actor.helth
function my_function()
...
end

Чтобы сосчитать значение переменной из другого скрипта достаточно в другом скрипте сделать так:
text="Я иду гулять по бродвею"
Теперь в нашем скрипте вызываем этот параметр
local pisanina = название скрипта . text
() - При таком обращении этот тег НЕ СТАВИТСЯ !

Смысловые значения функций.


if ..... then
....
end
Перевожу Если     что-то      то
конец тега.
Пример

if db.actor.psy==0.5 then
db.actor:kill(db.actor)
end
Если пси-здоровье ГГ - половина, то мы его убиваем.
Полная функция:

function my_function()
if db.actor.psy==0.5 then
db.actor:kill(db.actor)
end
end

Переделал с переменными(Для чего нужны объявления?):
[/color]
local acter = db.actor
function my_function()
local psy_zdorovie = acter.psy
if psy_zdorovie==0.5 then
acter:kill(acter)
end
end
Что я сделал?
Обозначил кусок db.actor локальной acter.
А acter.psy (db.actor)+.psy равносильно db.actor.psy

Вы поняли? Я поразбивал куски на локальные и код получился короче, функция имеет куда меньше знаков и удобнее к пониманию.
ВНИМАНИЕ!!!! Переменные должны объявлятся так, чтобы самое то, к чему обращаются было известно. Допустим...


local psy_zdorovie = acter.psy
Нам нужна эта acter перменная, и мы ДОЛЖНЫ ОБЪЯВИТЬ её перед переменной
localpsy_zdorovie = acter.psy .
Мы ее и объявили local acter = db.actor .
Думаю смысл понятен?

Комбинации логических выражений.


if ...... then
1 действие.
else
2 действие.
end

Перевод: Если подходит условие то
1 действие
иначе (т.е условие не выполняется)
2 действие
конец тега
Пример:

function my_function()
if db.actor.psy==0.5 then
db.actor:kill(db.actor)
else
db.actor.give_info_portion("info")
end
end

Если пси-здоровье актора равно половине, то мы его убиваем, если же значение другое(любое) , то даем ему инфопоршень.

Проверка нескольких условий


Допустим нам нужно проверить несколько условий:
Чтобы они все выполнялись!

if (db.actor) and (db.actor.helth==1) and (db.actor.psy ==0.5) then
действие
end
Функция сработает если есть актор и здоровье актора полное и псиздоровье половина .

Тег and - означает И . Если один из элементов не выполняется, то функция не срабатывает. Кстати - это ленивый метод, как писал Kamikaze , если не выполняется первый элемент, то другие - уже не просчитывааются. Т.е. не загнружается процесс....

Если подходит хоть один элемент.
if (db.actor) or (db.actor.helth==1) or (db.actor.psy ==0.5) then
действие
end

Тег or обозначает ИЛИ. Или один, или другой. Функция сработает при условии соответствия хоть одного элемента. Так же ленивый метод. Проверяет до получения утвердительного решения, потом проверка не идет.

Цепочка elseif .


Данный метод заменяет перебор через таблицу. Отличается простотой и потерей производительности.

if ...... then
самое основное действие
elseif ...... then
действие 1
elseif ...... then
действие 2
elseif ...... then
действие 3
elseif ...... then
действие 4
elseif ...... then
действие 5
end
Здесь представлен перебор elseif иначе если , т.е не подходит первый вариант, мы проверяем второй и так по цепочке , до первого подходящего(где выполняется заданное условие), если же ни одно не подойдет, то ничего не произойдет. Если бы мы просто в йункции написали кучу

function perebor()
if ..... then
действие
end
if ..... then
действие
end
if ..... then
действие
end
if ..... then
действие
end
if ..... then
действие
end
if ..... then
действие
end
end

Тон ничего хорошего не вышло бы. Так как проверялись бы все функции. А в первом варианте до первого попавшегося...

Переменная nil

Пременная нил указывает, что объекта , условия, да чего угодно НЕТ, его не существует.
ВСЕГДА проверяйте некоторые объекты на nil
Во первых это актор .
Можно написать

if (db.actor ~= nil) then
....
end

Но правильнее и эстетичнее, сразу писать так.

if (db.actor) then
....
end

Проверкой советую проверять многие элементы, так как в игре они зачастую не существуют в определенные моменты...

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


if имя скрипта then
......
end

if my then
......
end

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

Рандом.

Числовой.

math.random(1,100)
Данная функция рандомно выберет число от 1 до 100.
Сначала ставится наименьшее, потом наибольшее.
Если ставить десятичные , допустим (0.0005, 1), то перебуеруться ВСЕ значения, т.е числа с несколькими знаками, ТАК ДЕЛАТЬ НЕ НУЖНО. вы перегрузите некоторые элементы кода.
Использование

if math.random(0,1) < 1 then
действие
end
Если выбранное число меньше 1, то срабатывает функция.

Или так.

if math.random(0,1) < 1 then
действие
else
......
end
Добвавляется другое действие.
Советую брать целые числа от 1 до 10 для создания процентного срабатывания, но лучше 0 и 1.

Текстовый.
Допустим вы отправляете сообщение и хотите выбрать рандомный текст.
1) Создается таблица с вашими переменными (Это может быть и секция для спавна, и слово, и любая другая переменная)

localmy frazi = {"ага","да","нет!","конечно","несомненно"}

Так создается примитивная таблица, каждый элмент записывается в кавычках и отделяется отдельно.
Далее, обозначаем за переменную которая нам нужна. Допустим в функции вам нужна пременная text.
Мы и пишем .
localtext = my frazi[#(my frazi)]
И пр и срабатывании функции, обращении к переменной text, выберается рандомная переменная из таблицы
my frazi .

Перебор, повтор действия.



fori=1, 5000 do
действие
end

Это цикл, который прокрутнет ваше действие 5000 раз. Переменная i любая буква, число 5000 обозначает количество циклов(сколько раз пройдет ваше действие).


Передача параметра.

Допустим мы сделали такую функцию

-- удаляем объект из игры(Взято из АМК )

function remove(remove_item)
if remove_item~=nil then
alife():release(alife():object(remove_item:id()), true)
return true
end
return false
end
remove_item - это наш параметр, в данном случае это секция объекта, которую нужно удалить.
(немного по секция , если это уникальный объект, то это то,ч то в его конфиге, если нет, то нужно искать другим методом)
Нам нужно удалить уникального НПС vasek
Если функция находится в скрипте, где мы хотим удалить объект, то пишем
remove(vasek)
Если в другом скрипте, то
имя скрипта.remove(vasek)
Вот такой пример передачи параметра, передавать можно что угодно и как угодно. Было бы воображение.

Возвращение значений.

Допустим, идет проверка и если она оканчивается удачно, то функция должна вернуть одну переменную, если нет, то другую.

function my()
ifproverka() == truethen
.....
end
end

functionproverka()
if db.actor then
returntrue
else
returnfalse
end

Т.е мы хотим проверить наличие актора(можно что угодно). Создаем функцию proverka, она работает так, если актор есть - возвращает( return ) одну переменную, в данном случае true (Может быть любая другая) , если проверка не проходит, то возвращается false, а нашей первой my() стоит условие на то, что проверка вернет true
ifproverka() == truethen
Вот так, если вернет, то сработает первая функция.

Как их вызывать? Функции.

Функции вызваются из других скриптов, нужно лишь найти место. Если она вызывается постоянно. То нужно пихать в колбэк на апдет в bind_stalker.script

"Кусок кода"
Код
function actor_binder:update(delta)
object_binder.update(self, delta)

if string.find(command_line(), "-designer") then
return
end

if self.already_jumped==false and jump_level.need_jump==true and (device().frame > self.spawn_frame+2000) then
jump_level.try_to_jump()
self.already_jumped = true
return
end

-- Вызов апдейта переноса игрока проводником
if travel_func ~= nil then
travel_func()
end

-- DEBUG slowdown
--slowdown.update()
local time = time_global()
game_stats.update (delta, self.object)
-- апдейт погоды
self.weather_manager:update()

self:check_detective_achievement()
self:check_mutant_hunter_achievement()

--' Апдейт саундменеджера
xr_sound.update(self.object:id())

-- Обновление отключения ввода с клавиатуры.
if self.st.disable_input_time ~= nil and
game.get_game_time():diffSec(self.st.disable_input_time) >= self.st.disable_input_idle
then
level.enable_input()
self.st.disable_input_time = nil
end

-- Апдейт прятание оружия игрока во время диалога
if self.object:is_talking() then
if self.weapon_hide_in_dialog == false then
self.object:hide_weapon()
printf("hiding weapon!!!")
self.weapon_hide_in_dialog = true
end
else
if self.weapon_hide_in_dialog == true then
printf("restoring weapon!!!")
self.object:restore_weapon()
self.weapon_hide_in_dialog = false
end
end
-- Апдейт прятание оружия игрока в зоне sr_no_weapon
if check_for_weapon_hide_by_zones() == true then
if self.weapon_hide == false then
printf("hiding weapon!!!")
self.object:hide_weapon()
self.weapon_hide = true
end
else
if self.weapon_hide == true then
printf("restoring weapon!!!")
self.object:restore_weapon()
self.weapon_hide = false
end
end

-- обновление пси-антенны
if sr_psy_antenna.psy_antenna then
sr_psy_antenna.psy_antenna:update(delta)
end
--[[
--' Вывод сообщения о большой радиации
if self.object.radiation >= 0.7 then
local hud = get_hud()
local custom_static = hud:GetCustomStatic("cs_radiation_danger")
if custom_static == nil then
hud:AddCustomStatic("cs_radiation_danger", true)
hud:GetCustomStatic("cs_radiation_danger"):wnd():TextControl():SetTextST("st_radiation_danger")
end
else
local hud = get_hud()
local custom_static = hud:GetCustomStatic("cs_radiation_danger")
if custom_static ~= nil then
hud:RemoveCustomStatic("cs_radiation_danger")
end
end
]]--

if self.bCheckStart then
printf("SET DEFAULT INFOS")
if not has_alife_info("global_dialogs") then
self.object:give_info_portion("global_dialogs")
end
if not has_alife_info("level_changer_icons") then
self.object:give_info_portion("level_changer_icons")
end
self.bCheckStart = false

--if self.actor_weapon_on_start == true then
--db.actor:activate_slot(3)
--self.actor_weapon_on_start = false
--end
end
--device().precache_frame== 0 and
if not self.loaded_slot_applied then
self.object:activate_slot(self.loaded_active_slot)
self.loaded_slot_applied = true
end
xr_s.on_actor_update(delta)

if(self.surge_manager) then
if(self.f_surge_manager_loaded ~= true) then
self.surge_manager:initialize()
self.f_surge_manager_loaded = true
end
if(self.surge_manager.levels_respawn[level.name()]) then
self.surge_manager:respawn_artefacts_and_replace_anomaly_zone()
end
self.surge_manager:update()
end
-- Апдейт доступности для симуляции.
simulation_objects.get_sim_obj_registry():update_avaliability(alife():actor())

if not self.loaded then
get_console():execute("dump_infos")
self.loaded = true
end
treasure_manager.get_treasure_manager():update()

if not(primary_objects_filled) then
pda.fill_primary_objects()
primary_objects_filled = true
end
pda.fill_sleep_zones()
--СЮДА в САМЫЙ КОНЕЦ
end


В том же скрипте есть колбэки на взятие, потерю, использование предметов. Нужно лишь искать.....
Этим вы займетесь сами, или спросите у меня...

В диалогах можно вызывать через тег (без () )
Код
<action> имя скрипта.функция</action>

Есть еще способы через логику, но они вам сейчас не нужны, а как понадобятся, вы сами их найдете.
В этом деле главное терпение , находчивость и желание. Коды за вас никто писать не будет. В лучшем случае дадут пару советов и пошлют ]]>http://www.lua.ru/]]> . А в обычном скажут, руки не оттуда растут....


Возможны неточности.


Категория: Работа со скриптами | Добавил: drweb66 (25.03.2011)
Просмотров: 13504 | Рейтинг: 3.0/6
Всего комментариев: 0
avatar
PDA
Поиск
Как вы думаете,
Верите ли вы что СТАЛКЕР 2 выйдет?
Всего ответов: 2486
Сообщения
Разное
AP production - видео обзоры модов для игры S.T.A.L.K.E.R.

На территории Зоны: 1
Отмычек: 1
Опытных ходоков: 0


Design by:
Guenplenтм, with the participation of Orlenok Design Studio ®
Правообладателям
2024