Vano_Santuri 33 Опубликовано 5 Декабря 2009 (изменено) Базовый урок , ничего сложного, смарт-терейны не переписывал, сами будете добавлять....Назовем нашу группировку (айди) grom1) Открываем файл gamedata\configs\creatures\game_relations.ltx ;названия группировок (порядок должен совпадать с communities_relations) communities = actor, 0, bandit, 1, dolg, 2, ecolog, 3, freedom, 4, killer, 5, army, 6, monolith, 7, monster, 8, stalker, 9, zombied, 10, grom, 11 пишем группировку за следующей как в таблице, и указываем номер, по счету из таблицы, после последней запятая не нужна!!! [communities_relations] ; |actor|bandit| dolg|ecolog|freedom|killer| army|monolith|monster|stalker| zombied|grom ;=============================================================================== ==================== actor = 0, 0, 0, 0, 0, -1000, 0, -5000, -5000, 0, -5000 bandit = 0, 5000,-5000, 0, -5000, 0, -5000, -5000, -5000, -1000, -5000, -5000 dolg = 0, -5000, 5000, 0, -5000, 0, 0, -5000, -5000, 0, -5000, 0 ecolog = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 freedom = 0, -5000,-5000, 0, 5000, 0, 0, -5000, -5000, 0, -5000, 0 killer = -1000, 0, 0, 0, 0, 1000, -5000, -5000, -5000, 0, -5000, 0 army = 0, -5000, 0, 0, 0, -5000, 1000, -5000, -5000, 0, -5000, 0 monolith = -5000, -5000,-5000, 0, -5000, -5000, -5000, 1000, -5000, -5000, 1000, -5000 monster = -5000, -5000,-5000, 0, -5000, -5000, -5000, -5000, 0, -5000, -5000, -5000 stalker = 0, -1000, 0, 0, 0, 0, 0, -5000, -5000, 0, -5000, 5000 zombied = -5000, -5000,-5000, 0, -5000, -5000, -5000, 1000, -5000, -5000, 1000, -5000 grom = -5000, -1000, 0, 0, 0, 0, 0, -5000, -5000, 0, -5000, 5000 Добавляем группировку в таблицу, прописываем отношение к другим группировкам, НЕ ЗАБЫВАЕМ добавлять по еще одному значению по вертикали! ;(порядок должен совпадать с communities_relations) [communities_sympathy] actor = 0.0 bandit = 0.0 dolg = 0.0 ecolog = 0.0 freedom = 0.0 killer = 0.0 army = 0.0 monolith = 0.0 monster = 0.0 stalker = 0.0;0.01 zombied = 0.0 grom = 0.0 Сюда тоже добавляем в таком же порядке...2) Создаем профайл сталкера в gamedata\configs\gameplay\character_desc_general.xml (ну или другой, который вы прописали, или на уровнях) <specific_character id="grom spez" team_default = "1"> <name>GENERATE_NAME_stalker</name> <icon>ui_inGame2_merc_4</icon> <map_icon x="1" y="0"></map_icon> <bio>Опытный сталкер. Детальная информация отсутствует.</bio> <class>grom_specnaz</class> <community>grom</community> <terrain_sect>stalker_terrain</terrain_sect> <snd_config>characters_voice\human_03\killer\</snd_config> <rank>60</rank> <money min="5000" max="10000" infinitive="0"/> <reputation>0</reputation> <visual>actors\stalker_merc\stalker_merc_4</visual> <supplies> [spawn] \n wpn_fn2000 \n ammo_5.56x45_ap = 1 \n wpn_usp \n ammo_11.43x23_hydro = 1 \n grenade_f1 = 4 \n #include "gameplay\character_items_nd.xml" #include "gameplay\character_food.xml" #include "gameplay\character_drugs_4.xml" #include "gameplay\character_drugs_sci.xml" #include "gameplay\character_drugs_mil.xml" </supplies> #include "gameplay\character_criticals_4.xml" #include "gameplay\character_dialogs.xml" </specific_character> 3) в файле gamedata\configs\gameplay\npc_profile.xml создаем класс нпс, вписываем его айди из профайла и класс. <character id="grom spez"> <class>grom_specnaz</class> </character> В файле gamedata\configs\creatures\spawn_sections_general.ltx создаем секцию для спавна: [ваше название секции]:stalker $spawn = "respawn\ваше название секции" character_profile = grom spez -айди нпс_профайла spec_rank = novice community = grom ---группировка как в профайле 4) Добавляем в скрипт death_manager.script нашу группировку: local community_list = { "stalker", "dolg", "freedom", "bandit", "army", "zombied", "ecolog", "killer", "monolith","grom"} 5) В файле gamedata\configs\misc\death_items_by_communities.ltxДобавляем секцию с группировкой, и продукты для нее...., теоретически можно не трогать этот файл, все будет по дефолту и вылетов не будет тоже, проверял.6) Чтоб название было по русски в любом файле с текстами <string id="grom"> <text>Вольный сталкер</text> </string> 7) Осталось заспавнить, берем секции из spawn_sections_.... Изменено 20 Сентября 2014 пользователем World_Stalker Что-то кончается, что-то начинается... Поделиться этим сообщением Ссылка на сообщение
Vano_Santuri 33 Опубликовано 11 Августа 2010 (изменено) Я не профессионал, я не программист, я не изучал официальную справку по Lua, я не считаю себя гением и еще кем-либо.В данном топе вы найдете готовые, самые используемые скриптовые функции, начальные сведения по скриптованию, научитесь писать примитивные скрипты(хотя их такими не назовешь), но я не смогу передать вам мой образ мышления и способность находить ответы на многие вопросы самому методом общего анализа...(Данный материал я считаю своей интеллектуальной собственностью, если вы хотите опубликовать его еще где-то, то обязательно указывайте автора(да и пора бы уже научиться всегда указывать авторов,даже без требования) и не так: "ой забыл", "где-то видел", "какой-то чувак", а ник. Если вам понравился материал, можете и ссылку на данный форум скинуть(замаскировав под гиперссылку с текстом), я буду только благодарен.) Урок первый. Что такое скрипт?1. Все файлы скрипты находятся в папке gamedata\scripts.2. Файл скрипта - это текстовый файл имеющий расширение .script.3. В С.Т.А.Л.К.Е.Р используется немного изменённый скриптовый язык Lua 5.1.4. Для редактирования скриптов я советую NotePad c++, данная программа имеет подсветку синтаксиса для многих языков, в том числе и для Lua. Чтобы активировать подсветку нажмите клините Стиль - Lua .5. Чтобы закомментировать строку (код игры не будет ёё читать), необходимо перед строкой поставить -- .Если вы хотите закомментировать кусок (много строк) то --[[ .... ]] , ваш текст будет закоментирован.Начнём уроки.1) Создадим свой my.scripts и поместим его в папку scripts. Откроем с помощью Нотепада и настроим подсветку.2) Внутри файла-скрипта должны содержаться только КОД скрипта и ваши Закомментированные пометки. Если будет лишний текст, т.е какие-то знаки и слова, то будет вылет на этот скрипт. Так как код игры полностью собирает весь скрипт в стек и выбирает только то, что вы задали, но если будет мусор, то игра не воспримет код.3) Архитектур. Для создания функций нужны лишь знания синтаксиса и игровые методы и глобальные функции(которые записаны в движке) можете почитать lua_help.script , но я советую посетить тему на АМК . Там собраны все методы, классы и полное их описание.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 Переделал с переменными(Для чего нужны объявления?): 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 переменная, и мы ДОЛЖНЫ ОБЪЯВИТЬ её перед переменной local psy_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 указывает, что объекта , условия, да чего угодно НЕТ, его не существует.ВСЕГДА проверяйте некоторые объекты на 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) Создается таблица с вашими переменными (Это может быть и секция для спавна, и слово, и любая другая переменная) local my frazi = {"ага","да","нет!","конечно","несомненно"} Так создается примитивная таблица, каждый элмент записывается в кавычках и отделяется отдельно.Далее, обозначаем за переменную которая нам нужна. Допустим в функции вам нужна пременная text.Мы и пишем: local text = my frazi[#(my frazi)] И пр и срабатывании функции, обращении к переменной text, выбирается рандомная переменная из таблицыmy frazi.Перебор, повтор действия. for i=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() if proverka() == truethen ..... end end function proverka() if db.actor then return true else return false end Т.е мы хотим проверить наличие актора(можно что угодно). Создаем функцию proverka, она работает так, если актор есть - возвращает( return ) одну переменную, в данном случае true (Может быть любая другая) , если проверка не проходит, то возвращается false, а нашей первой my() стоит условие на то, что проверка вернет true if proverka() == true then Вот так, если вернет, то сработает первая функция. Как их вызывать? Функции.Функции вызываются из других скриптов, нужно лишь найти место. Если она вызывается постоянно. То нужно пихать в коллбэк на апдейт в bind_stalker.script [color=#404000]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. А в обычном скажут, руки не оттуда растут....Возможны неточности. Изменено 20 Сентября 2014 пользователем World_Stalker 3 8 2 Что-то кончается, что-то начинается... Поделиться этим сообщением Ссылка на сообщение