|
|
Строка 1: |
Строка 1: |
− | ==Теория==
| + | Наш сервис предоставляет настоящие лайки на фотографии заказчиков, которые готовы платить за качество. |
− | | + | |
− | В скриптах есть одна единственная функция, отвечающая за спавн объектов:
| + | |
− | | + | |
− | <lua>
| + | |
− | alife():create(section,position,levelvertex,gamevertex)
| + | |
− | </lua>
| + | |
− | | + | |
− | <span style="color: gray">Строго говоря, их две: create и create_ammo но различия между ними не существенны. [[Участник:Imp|Imp]] 22:45, 23 июля 2007 (EEST)</span>
| + | |
− | | + | |
− | Первый параметр - секция в конфигурациях, описывающая объект, например "bolt","medkit" - это простые секции, простых объектов
| + | |
− | а есть объекты, которые переходят в онлайн/оффлайн, это неписи, монстры и так далее, например mil_killer_respawn_2 - спавнится снайпер группировки киллеров.
| + | |
− | | + | |
− | С позицией, думаю объяснять не надо, только существует нюанс - высота это Y, а не Z.
| + | |
− | | + | |
− | [http://images.gameru.net/image/direct/5e560ebeb5.jpg Направления в пространстве]
| + | |
− | | + | |
− | Задать позицию можно такой конструкцией: vector():set(x,y,z), где x, y и z - координаты точки на уровне, где спавним объект.
| + | |
− | | + | |
− | Вертекс в игре Сталкер не тоже самое, что вертекс в трехмерной графике. Vertex - определенная зона малого размера за которой закреплен индивидуальный номер в пределах уровня или целой игры.
| + | |
− | level_vertex определяет зону на уровне, по которой можно пройти NPC. game_vertex определяют зоны для свободного хождения, т.е. под руководством ИИ, а также между уровнями. Вертексы имеют одно из первостепенных значений. Точность положения указывается уже через точку спавна.
| + | |
− | Например, можно получить вертекс ближайший к актору - db.actor:level_vertex_id()
| + | |
− | | + | |
− | game_vertex_id нужен для того, чтобы указать на какой карте спавнить объект.
| + | |
− | | + | |
− | Соответственно, чтобы заспавнить что-нибудь на другой карте, достаточно указать game_vertex_id в четвертом параметре.
| + | |
− | Например:
| + | |
− | | + | |
− | <lua>
| + | |
− | db.actor:game_vertex_id()
| + | |
− | </lua>
| + | |
− | | + | |
− | Итак, чтобы, например, заспавнить болт под ногами актора, пишем:
| + | |
− | | + | |
− | <lua>
| + | |
− | alife():create("bolt", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id())
| + | |
− | </lua>
| + | |
− | | + | |
− | Почему 1, а не level_vertex_id? Проверено - разницы особой нет, какой level_vertex_id, хотя в некоторых случаях надо прописывать валидный вертекс, а то предмет может просто заспавнится не там, где планировалось... Но по большей части все проходит нормально и с единицей (игнорирование level_vertex_id может приводить к проваливанию произведенных предметов/персонажей под землю).
| + | |
− | А вот game_vertex решает все - он указывает на каком уровне спавнить предмет, поэтому его надо указывать. Теоретически можно просто найти для каждого уровня по одному game_vertex'у и использовать их в скриптах.
| + | |
− | На самом деле game_vertex показывает какой фрагмент карты используется (вся карта разбита на кусочки, имеющие сквозную нумерацию по всем уровням, и game_vertex выбирает нужный) соответственно неправильное использование черевато....
| + | |
− | | + | |
− | Кроме того, есть еще один параметр - ID объекта, если указать ID NPC или актора - то предмет заспавнится у него в инвентаре.
| + | |
− | | + | |
− | Пример (спавним артефакт Медуза в инвентаре у актора):
| + | |
− | | + | |
− | <lua>
| + | |
− | alife():create("af_medusa", db.actor:position(), 1, db.actor:game_vertex_id(), db.actor:id())
| + | |
− | </lua>
| + | |
− | | + | |
− | Функция спавна возвращает серверный объект, то есть ни NPC, ни монстра ни что-либо еще.
| + | |
− | | + | |
− | <span style="color: gray">Серверный обьект позволяет свежесозданного NPC или тайник затарить разными рулезами/артефактами. Например, вот так создадим перед входом к Сидоровичу долговца и засунем в него пачку патронов:
| + | |
− | <lua>
| + | |
− | local obj
| + | |
− | local a = vector() -- Задаем тип переменной
| + | |
− | local dir = db.actor:direction()
| + | |
− | | + | |
− | a.x = -243.61 -- координата X
| + | |
− | a.y = -19.52 -- высота Y
| + | |
− | a.z = -127.17 -- координата Z
| + | |
− | | + | |
− | obj = alife():create("bar_dolg_respawn_3", a, 13193, 8, 65535)
| + | |
− | alife():create_ammo("ammo_9x18_fmj",
| + | |
− | obj.position,
| + | |
− | obj.m_level_vertex_id,
| + | |
− | obj.m_game_vertex_id,
| + | |
− | obj.id,
| + | |
− | 20) -- число патронов
| + | |
− | </lua>
| + | |
− | | + | |
− | Кстати, create_ammo - практически тоже самое, что и create, разница в том, что create_ammo предназначена специально для спавна патронов и позволяет создавать неполные пачки патронов. Возможно есть еще какие-то отличия. Стоит учесть, что сами авторы игры спавнят патроны исключительно через create_ammo. [[Участник:Imp|Imp]] 22:38, 23 июля 2007 (EEST)</span>
| + | |
− | | + | |
− | Просто минимальный набор - координаты, ID, секция,а из него (серверного объекта) обычно нужен только ID, так как по ID можно получить этот самый серверный объект:
| + | |
− | | + | |
− | <lua>
| + | |
− | (alife():object(id))
| + | |
− | </lua>
| + | |
− | | + | |
− | Его можно использовать, чтобы поставить метку, например, но я его лично использую для других целей - спавн сложных объектов, конкретно – NPC.
| + | |
− | | + | |
− | Например надо решить следующую задачу - надо создать наемника, сменить ему группировку и изменить его инвентарь, ну и в нагрузку - сделать другом для игрока.
| + | |
− | | + | |
− | В определенный момент заспавненный объект переходит онлайн, в этот момент вызывается callback - net_spawn.
| + | |
− | | + | |
− | Что мы делаем? Сверяем ID онлайн объекта с сохраненным ID!
| + | |
− | | + | |
− | Если они совпадают, например так:
| + | |
− | | + | |
− | <lua>
| + | |
− | if obj:id()==saved_id then ...
| + | |
− | </lua>
| + | |
− | | + | |
− | Важно то, что у серверного объекта ID - это параметр, а у онлайнового объекта ID получается с помощью функции. Это важно, а то можно прогореть.
| + | |
− | | + | |
− | Итак, мы поймали нашего киллера по ID.
| + | |
− | | + | |
− | Далее все очень просто - вызываем команды для спавна гаусса и патронов к нему в инвентаре NPC (см. выше), меняем группировку специальной функцией, и делаем его другом.
| + | |
− | | + | |
− | Зачем такие сложности? Просто в оффлайне NPC как бы не существует, есть только косвенное упоминание о нем, и, плюс, все эти функции работают именно с объектом типа "NPC", а не с серверными объектами.
| + | |
− | | + | |
− | Более простая функция спауна в одну строчку:
| + | |
− | | + | |
− | <lua>
| + | |
− | alife():create(section,position,levelvertex,gamevertex)
| + | |
− | </lua>
| + | |
− | | + | |
− | section -- это секция предмета
| + | |
− | position -- это его позиция (Через vector()) Брать в игре с помощью консольной команды rs_stats 1 или rs_cam_pos 1 (Тока в ЧН)
| + | |
− | levelvertex - пусть равно 1
| + | |
− | gamevertex - его Game Vertex, определяет уровень где будет спаун.
| + | |
− | GV можно взять либо скриптом, либо через распакованный all.spawn.
| + | |
− | | + | |
− | Пример:
| + | |
− | | + | |
− | <lua>
| + | |
− | alife():create("stalker",vector():set(0,0,0),1,135) -- спаунит сталкера на водокачке (игра ЧН, на уровне Болото).
| + | |
− | </lua>
| + | |
− | | + | |
− | ==Практика (часть 1)==
| + | |
− | | + | |
− | '''1.''' Чтобы не повторяться в описании создания нового квеста, просто изучите [[Создание квестов (Fr3nzy)|статью по созданию квестов]] от Fr3nzy – лучшей статьи на эту тему я просто не видел :) Мы просто свяжем все воедино и научимся спавнить объекты из скрипта.
| + | |
− | | + | |
− | Небольшое отступление:
| + | |
− | | + | |
− | Почему предпочтительнее делать спавн скриптом, а не через тот же [http://stalkerin.gameru.net/downloads/stutils/zeed/xrspawner.rar xrSpawner]? Программа xrSpawner, при всех своих достоинствах, обладает одним недостатком, а именно – редактирует спавн через файл all.spawn, что приводит к:
| + | |
− | | + | |
− | * Невозможности совместить два мода, такой спавн использующих
| + | |
− | * Необходимости каждый раз начинать новую игру
| + | |
− | | + | |
− | При спавне через скрипт ситуация иная: в подавляющем большинстве случаев, ранее сохранённые игры будут работать, что не может не радовать :)
| + | |
− | | + | |
− | Итак, определимся с квестом.
| + | |
− | | + | |
− | '''Задача:''' после разговора с Сидоровичем спавним зомби на территории фабрики в первой локации. Для того, чтобы не повредить оригинальный сюжет игры, задание будет выдаваться '''после''' прохождения квеста с флешкой Шустрого, так как появись там зомби одновременно с бандитами и Шустрым... я думаю, исход боя предрешен :)
| + | |
− | | + | |
− | Реализация: Постараюсь описать все действия максимально подробно, буквально по шагам. Первым делом запустите игру :)
| + | |
− | | + | |
− | В консоли введите команду:
| + | |
− | | + | |
− | <ini>
| + | |
− | rs_stats on или rs_stats 1
| + | |
− | </ini>
| + | |
− | | + | |
− | Тем самым мы включаем вывод информации на экран.
| + | |
− | Далее вводим еще одну команду:
| + | |
− | | + | |
− | <ini>
| + | |
− | demo_record 1
| + | |
− | </ini>
| + | |
− | | + | |
− | И «летим» на фабрику. Нам нужно выбрать место для спавна объектов и данный режим как нельзя лучше подходит для реализации задуманного. Помещаем камеру в точке предполагаемого спавна и записываем координаты - у меня получились 115, -6, -16.
| + | |
− | | + | |
− | Для выхода из режима demo_record нажимаем Esc, в консоли пишем rs_stats off или rs_stats 0 (убираем вывод информации).
| + | |
− | | + | |
− | <span style="color: gray">Другой способ получения тех же сведений - прийти в нужное место и запустить там скрипт, который выдаст все нужные координаты. Я пользуюсь следующим скриптом (вызываю общеизвестным способом, через main_menu):
| + | |
− | | + | |
− | <lua>
| + | |
− | function main_menu:main_cheat_f3()
| + | |
− | -- Выдадим сообщение о нашем местоположении
| + | |
− | local text
| + | |
− | local vid
| + | |
− | local gvid
| + | |
− | local a = vector() -- Тип переменной
| + | |
− | local text
| + | |
− | | + | |
− | a = db.actor:position() -- Наше положение в координатах
| + | |
− | vid = db.actor:level_vertex_id()
| + | |
− | gvid = db.actor:game_vertex_id()
| + | |
− | text = "Позиция:\\nX= "..a.x.."\\nY= "..a.y.."\\nZ= "..a.z.."\\nlevel_vertex= "..vid.."\\ngame_vertex_id= "..gvid
| + | |
− | news_manager.send_tip(db.actor, text, nil, nil, 30000)
| + | |
− | end
| + | |
− | </lua>
| + | |
− | | + | |
− | В результате не нужно экспериментировать, мы сразу получаем все, в том числе и level_vertex и game_vertex. [[Участник:Imp|Imp]] 22:38, 23 июля 2007 (EEST)</span>
| + | |
− | | + | |
− | <span style="color: gray">
| + | |
− | Или же используем готовые скрипты с автообновлением позиционирования:
| + | |
− | <br>
| + | |
− | [http://stalkerin.gameru.net/downloads/stutils/LVIDGVID_script.7z LVID GVID Script SoC]
| + | |
− | <br>
| + | |
− | [http://stalkerin.gameru.net/downloads/stutils/script_position_cs.rar LVID GVID Script CS]
| + | |
− | <br>
| + | |
− | [http://stalkerin.gameru.net/downloads/stutils/LVID_GVID_COP.rar LVID GVID Script CoP]
| + | |
− | <br>
| + | |
− | [http://stalkerin.gameru.net/downloads/stutils/lv_gv_id_3120.rar LVID GVID Script 3120]
| + | |
− | <br>
| + | |
− | [http://stalkerin.gameru.net/downloads/stutils/LVIDGVID_script_amk.7z LVID GVID Script AMK]
| + | |
− | <br>
| + | |
− | [[Участник:RedPython|RedPython]] 16:09, 10 октября 2010 (UTC)
| + | |
− | </span>
| + | |
− | | + | |
− | Выходим из игры, идем в папку с установленной игрой и создаем каталог gamedata (предполагается, что «лепим» свой «мод» на «чистую» игру, без установленных модов, и имеем распакованные ресурсы игры в папке, скажем, gamedata source).
| + | |
− | | + | |
− | В папке gamedata создаем папку config, а в ней - папку creatures. Скопируем из оригинальной папки файл m_zombie.ltx и откроем его на редактирование.
| + | |
− | | + | |
− | В файлах игры присутствуют 5 моделей гражданских зомби: файлы zombi_1.ogf, zombi_1_ghost.ogf, zombi_2.ogf, zombi_trup.ogf, zombi_trup_2.ogf.
| + | |
− | | + | |
− | Вернем в игру их всех :)
| + | |
− | | + | |
− | Уже имеются секции:
| + | |
− | | + | |
− | <pre>
| + | |
− | [zombie_weak]:m_zombie_e, [zombie_normal]:m_zombie_e, [zombie_strong]:m_zombie_e и [zombie_immortal]:zombie_strong.
| + | |
− | </pre>
| + | |
− | | + | |
− | Два последних типа используют одну и ту же модель zombi_trup.ogf, хм... непорядок, исправляем.
| + | |
− | Последняя секция выглядит теперь так:
| + | |
− | | + | |
− | <ini>
| + | |
− | [zombie_immortal]:zombie_strong
| + | |
− | $spawn = "monsters\zombies\zombie_immortal"
| + | |
− | visual = monsters\zombi\zombi_trup_2
| + | |
− | panic_threshold = 0.05
| + | |
− | </ini>
| + | |
− | | + | |
− | Добавим пятую модель.
| + | |
− | | + | |
− | Для этого в конце файла создадим секцию:
| + | |
− | <ini>
| + | |
− | [zombie_ghost]:zombie_strong
| + | |
− | </ini>
| + | |
− | | + | |
− | Это означает, что наш пятый зомби наследует все параметры zombie_strong, мы добавим лишь визуальное представление.
| + | |
| | | |
− | Пишем дальше:
| + | Именно для этого мы и набираем удалённых сотрудников, которые будут выполнять работу, то есть ставить лайки и получить за это деньги. |
− | | + | |
− | <ini>
| + | Чтобы стать нашим удалённым сотрудником и начать ставить лайки, зарабатывая при этом 45 рублей за 1 поставленный лайк, |
− | $spawn = "monsters\zombies\zombie_ghost"
| + | |
− | visual = monsters\zombi\zombi_1_ghost
| + | достаточно просто зарегистрироваться на нашем сервисе. > like.zarplatt.ru < |
− | </ini>
| + | |
− | | + | |
− | Все. Сохраняем изменения и закрываем файл.
| + | |
− | | + | |
− | '''2.''' Пишем скрипт спавна. В папке gamedata создаем новую папку scripts, в ней создаем новый текстовый документ и называем его esc_zombie.script.
| + | |
− | | + | |
− | Отступление третье:
| + | |
− | | + | |
− | При написании статьи использовался оригинальный скрипт zombie_story.script из horror-mod’а. Концепция спавна перенесена практически без изменений, поэтому на авторство этого способа спавна я никоим образом не претендую :)
| + | |
− | | + | |
− | Итак, открываем наш пустой файл на редактирование, первой строкой объявляем переменную, в которой хранятся наши зомби:
| + | |
− | | + | |
− | <lua>
| + | |
− | local zombie_types = {"zombie_weak", "zombie_normal", "zombie_strong", "zombie_immortal", "zombie_ghost"}
| + | |
− | </lua>
| + | |
− | | + | |
− | Далее пишем функцию:
| + | |
− | | + | |
− | <lua>
| + | |
− | function spawn_zombies( position, total )
| + | |
− | local zombie_index -- тип зомби из массива zombie_types
| + | |
− | local new_pos, x_offset, z_offset -- объявляем переменные
| + | |
− | for zombie_index=1, total do -- крутим цикл столько раз, сколько задает переменная total
| + | |
− | x_offset = math.random(5) -- случайное (рандомное) x от 1 до 5
| + | |
− | z_offset = math.random(5) -- случайное (рандомное) z от 1 до 5
| + | |
− | new_pos = position -- передаем координаты в функцию
| + | |
− | new_pos.x = new_pos.x + x_offset -- прибавляем к указанной нами координате x полученное выше рандомное x
| + | |
− | new_pos.z = new_pos.z + z_offset -- прибавляем к указанной нами координате z полученное выше рандомное z
| + | |
− | -- Ниже, собственно и вызывается функция спавна случайного типа зомби zombie_types[math.random(5)] привязанного к нашим координатам
| + | |
− | alife():create(zombie_types[math.random(5)],new_pos,db.actor:level_vertex_id(),db.actor:game_vertex_id())
| + | |
− | end
| + | |
− | end
| + | |
− | | + | |
− | </lua>
| + | |
− | | + | |
− | И последнее:
| + | |
− | | + | |
− | <lua>
| + | |
− | function zombie_story_1( actor, npc )
| + | |
− | -- десять зомби на фабрике (Кордон)
| + | |
− | local spawn_point = vector():set( 115, -6, -16 ) -- здесь указываем координаты,
| + | |
− | -- выбранные нами для спавна, когда «летали» камерой :)
| + | |
− | spawn_zombies( spawn_point, 10 ) -- собственно вызов предыдущей функции
| + | |
− | -- с передачей ей координат и количества объектов
| + | |
− | end
| + | |
− | </lua>
| + | |
− | | + | |
− | Все. Сохраняем и закрываем файл.
| + | |
− | | + | |
− | Продолжаем разговор :)
| + | |
− | | + | |
− | Для того, чтобы игра не вылетала после того, как мы добавили новый тип монстров, их нужно добавить в файл xr_statistic.script. Итак, скопируем этот файл из папки ресурсов игры scripts в нашу папку к файлу esc_zombie.script и откроем на редактирование.
| + | |
− | | + | |
− | Добавим в local killCountProps к монстрам строчку:
| + | |
− | <lua>
| + | |
− | zombie_weak = 1, zombie_normal = 2, zombie_strong = 3, zombie_immortal = 4, zombie_ghost = 5
| + | |
− | </lua>
| + | |
− | | + | |
− | В local sect_alias после строки:
| + | |
− | | + | |
− | <lua>
| + | |
− | zombied_novice = 1, zombied_experienced = 2, zombied_veteran = 3, zombied_master = 4,
| + | |
− | </lua>
| + | |
− | | + | |
− | Допишем эти строки:
| + | |
− | | + | |
− | <lua>
| + | |
− | zombie_weak = "zombie_weak", zombie_normal = "zombie_normal", zombie_strong = "zombie_strong",
| + | |
− | zombie_immortal = "zombie_immortal", zombie_ghost = "zombie_ghost",
| + | |
− | </lua>
| + | |
− | | + | |
− | А ниже в monster_classes строчку:
| + | |
− | | + | |
− | <lua>
| + | |
− | [clsid.zombie_s] = "zombie"
| + | |
− | </lua>
| + | |
− | | + | |
− | В функцию getNpcType(npc) добавляем конструкцию:
| + | |
− | | + | |
− | <lua>
| + | |
− | elseif npc:character_community() == "zombie" then
| + | |
− | community = "zombie"
| + | |
− | </lua>
| + | |
− | | + | |
− | Сохраняем изменения и закрываем файл.
| + | |
− | | + | |
− | Все будет работать на ура, пока мы не попробуем обыскать убитого зомби. Как только мы это сделаем, игра вылетит с примерно такой ошибкой.
| + | |
− | | + | |
− | <ini>
| + | |
− | Expression : fatal error
| + | |
− | Function : CInifile::r_string
| + | |
− | File : D:\xray-svn\xrCore\Xr_ini.cpp
| + | |
− | Line : 351
| + | |
− | Description : <no expression>
| + | |
− | Arguments : Can't find variable icon in [zombie_weak]
| + | |
− | </ini>
| + | |
− | | + | |
− | Все верно – игра не знает, какую иконку нам показывать для зомби. Иконки монстров хранятся в файле ui_npc_monster.dds. Здесь есть два варианта:
| + | |
− | | + | |
− | * Если дружите с Фотошопом, отредактировать этот файл (нарисовать, добавить иконки);
| + | |
− | * Взять готовый из любого мода, естественно, с разрешения авторов мода. Сейчас мы пропустим данный аспект и присвоим нашим зомби иконки контролера :)
| + | |
− | | + | |
− | Вернемся к файлу m_zombie.ltx и в секцию [m_zombie_e]:monster_base впишем параметр
| + | |
− | <ini>
| + | |
− | icon = ui_npc_monster_kontroler
| + | |
− | </ini>
| + | |
− | | + | |
− | Все. Вылетов не будет.
| + | |
− | | + | |
− | 3. Тема данной статьи не предусматривает подробного описания того, как сделать новый диалог. В начале статьи я упомянул источник, где можно найти исчерпывающую информацию по созданию диалогов, могу также привести в пример [[Создание диалогов|статью по созданию диалогов]] от BAC9-FLCL.
| + | |
− | | + | |
− | Нам нужно просто проверить работоспособность скриптового спавна, поэтому я приведу просто собственно сам измененный диалог из файла dialogs_escape.xml:
| + | |
− | | + | |
− | <xml>
| + | |
− | <dialog id="escape_trader_talk_info">
| + | |
− | ………
| + | |
− | ………
| + | |
− | ………
| + | |
− | <phrase id="999">
| + | |
− | <text>escape_trader_talk_info_999</text>
| + | |
− | <next>7770</next>
| + | |
− | <next>9991</next>
| + | |
− | <next>9992</next>
| + | |
− | <next>9993</next>
| + | |
− | <next>9994</next>
| + | |
− | <next>9995</next>
| + | |
− | <next>9996</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="9992">
| + | |
− | <text>escape_trader_talk_info_9992</text>
| + | |
− | <next>99922</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="99922">
| + | |
− | <text>escape_trader_talk_info_99922</text>
| + | |
− | <next>9996</next>
| + | |
− | <next>9995</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="9993">
| + | |
− | <text>escape_trader_talk_info_9993</text>
| + | |
− | <next>99933</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="9995">
| + | |
− | <text>escape_trader_talk_info_9995</text>
| + | |
− | </phrase>
| + | |
− | <phrase id="3121">
| + | |
− | <text>escape_trader_talk_info_3121</text>
| + | |
− | <next>9996</next>
| + | |
− | <next>9995</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="3131">
| + | |
− | <text>escape_trader_talk_info_3131</text>
| + | |
− | <next>9996</next>
| + | |
− | <next>9995</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="41">
| + | |
− | <text>escape_trader_talk_info_41</text>
| + | |
− | <next>9996</next>
| + | |
− | <next>9995</next>
| + | |
− | </phrase>
| + | |
− | <!------Наш диалог: Начало------->
| + | |
− | <phrase id="7770">
| + | |
− | <text>escape_trader_talk_info_7770</text>
| + | |
− | <next>7771</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="7771">
| + | |
− | <text>escape_trader_talk_info_7771</text>
| + | |
− | <next>7772</next>
| + | |
− | <next>7773</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="7772">
| + | |
− | <text>escape_trader_talk_info_7772</text>
| + | |
− | <next>7777</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="7773">
| + | |
− | <text>escape_trader_talk_info_7773</text>
| + | |
− | <next>7779</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="7779">
| + | |
− | <text>escape_trader_talk_info_7779</text>
| + | |
− | <next>9996</next>
| + | |
− | <next>9995</next>
| + | |
− | </phrase>
| + | |
− | <phrase id="7777">
| + | |
− | <text>escape_trader_talk_info_7777</text>
| + | |
− | <action>esc_zombie.zombie_story_1</action>
| + | |
− | <next>9996</next>
| + | |
− | <next>9995</next>
| + | |
− | </phrase>
| + | |
− | <!------Наш диалог: Конец------->
| + | |
− | <phrase id="51">
| + | |
− | <text>escape_trader_talk_info_51</text>
| + | |
− | <next>9996</next>
| + | |
− | <next>9995</next>
| + | |
− | </phrase>
| + | |
− | ………
| + | |
− | ………
| + | |
− | ………
| + | |
− | </dialog>
| + | |
− | </xml>
| + | |
− | | + | |
− | И также связанный с ним файл stable_dialogs_escape.xml.
| + | |
− | В самом начале файла пишем следующее:
| + | |
− | | + | |
− | <xml>
| + | |
− | <string id="escape_trader_talk_info_7770">
| + | |
− | <text>Происшествий никаких не было?</text>
| + | |
− | </string>
| + | |
− | <string id="escape_trader_talk_info_7771">
| + | |
− | <text>Да знаешь... Вроде как тихо все у нас. Хотя, вот, вспомнил! Говорили мне
| + | |
− | на днях, что на фабрике, ну, там, где бандюки околачиваются постоянно, видели какиих-то то ли
| + | |
− | людей, то ли призраков... Мало ли что спьяну почудится - я и сказал этим паникерам, мол,
| + | |
− | закусывать надо! Хех, блин, алкаши...</text>
| + | |
− | </string>
| + | |
− | <string id="escape_trader_talk_info_7772">
| + | |
− | <text>Дык мне по любому мимо фабрики топать - заодно и посмотрю на этих
| + | |
− | "людей-призраков".</text>
| + | |
− | </string>
| + | |
− | <string id="escape_trader_talk_info_7773">
| + | |
− | <text>Да я как-то не собирался в ту сторону...</text>
| + | |
− | </string>
| + | |
− | <string id="escape_trader_talk_info_7779">
| + | |
− | <text>Ну, смотри сам, все равно будь осторожен.</text>
| + | |
− | </string>
| + | |
− | <string id="escape_trader_talk_info_7777">
| + | |
− | <text>Ага. Сходи, проветрись. Потом зайдешь, расскажешь, что там и как.</text>
| + | |
− | </string>
| + | |
− | <string id="esc_bridge_soldiers_start_11">
| + | |
− | <text>Здесь проход воспрещён, сталкер.</text>
| + | |
− | </string>
| + | |
− | </xml>
| + | |
− | | + | |
− | Все. Можно запускать игру, идти на Кордон, после разговора с Сидоровичем, в зависимости
| + | |
− | от выбранного Меченным решения, бежим на фабрику и … смотрим сами :)
| + | |
− | | + | |
− | [http://www.sendspace.com/file/2kx7uf Готовые файлы примера](перезалито)
| + | |
− | [http://slil.ru/24600587 Spawn Lib]
| + | |
− | | + | |
− | Домашнее задание - вернуть в игру 6-ой тип гражданского зомби :)
| + | |
− | | + | |
− | Продолжение следует…
| + | |
− | | + | |
− | ==Практика (часть 2)==
| + | |
− | | + | |
− | '''4.''' Сегодня мы закончим с зомби в полном объеме – добавим их описания в энциклопедию, добавим иконки, и разберемся с «домашним заданием»:) Думаю, что внимательно изучив эту статью, вы ''сами'' сможете через скриптовые функции восстановить любого персонажа, не вошедшего в финальный релиз игры. Если у кого хватит времени и желания, те могут даже написать что-то типа «Ночи живых мертвецов» :) - серию квестов, связанную своим собственным сюжетом.
| + | |
− | Итак, «домашнее задание» - добавляем в игру шестого зомби.
| + | |
− | | + | |
− | * Создаем в папке gamedata папку meshes, в ней папку monsters, а там – папку zombi. В папке meshes хранятся модели персонажей, объектов, окружения, присутствующих в игре. Как я уже говорил выше, в игре представлено 5 моделей гражданских зомби, а вот текстур – 6. Также немного смутила нумерация моделей – 1, 2, 4... А где третий? Наверное, сбежал :)
| + | |
− | | + | |
− | * Скопируем из папки с оригинальными файлами игры в созданную нами папку файл zombi файл zombi_2.ogf и переименуем его в zombi_3.ogf. Откроем файл нашей новой модели любым HexEditor’ом, я использую BiEd (Binary Editor 1.00). Так как данная статья рассчитана не только на «продвинутых юзеров», но и на «обычных чайников», которые, тем не менее, хотят «что-нить замутить» и при этом не сильно «парить моск», я не буду рассказывать здесь про адресацию, двухбайтовую запись и т.д., я просто наглядно покажу, где что поправить :)
| + | |
− | | + | |
− | [http://www.golushkov.pp.net.ua/photo/11-0-717-3 Файл модели '''до''' редактирования]
| + | |
− | | + | |
− | [http://www.golushkov.pp.net.ua/photo/11-0-718-3 Файл модели '''после''' редактирования]
| + | |
− | | + | |
− | На скринах видно, что мы просто изменили для этой модели путь к текстуре. Все. Без использования 3D-редакторов и затраты кучи времени на обработку модели в них, мы получили абсолютно новую (на внешний вид) модель. :)
| + | |
− | | + | |
− | '''5.''' Теперь пропишем нашего нового зомби во все файлы, которые мы создали ранее. В файл m_zombie.ltx в самый конец добавляем секцию:
| + | |
− | | + | |
− | <ini>
| + | |
− | [zombie_old]:zombie_normal
| + | |
− | $spawn = "monsters\zombies\zombie_old"
| + | |
− | visual = monsters\zombi\zombi_3
| + | |
− | </ini>
| + | |
− | | + | |
− | в файле esc_zombie.script изменяем массив в первой строке:
| + | |
− | | + | |
− | <lua>
| + | |
− | local zombie_types = {"zombie_weak", "zombie_normal", "zombie_strong", "zombie_immortal",
| + | |
− | "zombie_old", "zombie_ghost"}
| + | |
− | </lua>
| + | |
− | | + | |
− | В функции spawn_zombies изменяем строку спавна:
| + | |
− | | + | |
− | <lua>
| + | |
− | alife():create(zombie_types[math.random(6)],new_pos,
| + | |
− | db.actor:level_vertex_id(),db.actor:game_vertex_id())
| + | |
− | </lua>
| + | |
− | | + | |
− | В функции zombie_story_1 меняем число объектов на кратное 6-ти (необязательно):
| + | |
− | | + | |
− | <lua>
| + | |
− | spawn_zombies( spawn_point, 12 )
| + | |
− | </lua>
| + | |
− | | + | |
− | Всё. Сохраняем и закрываем.
| + | |
− | | + | |
− | '''6.''' Копируем в папку gamedata\config\gameplay\ файл encyclopedia_mutants.xml, добавляем описание зомби в энциклопедию:
| + | |
− | | + | |
− | <xml>
| + | |
− | <!-------------------------------- Zombieg ----------------------------->
| + | |
− | | + | |
− | <article id="mutant_zombieg_general" name="Zombieg" group="Mutants">
| + | |
− | <texture>ui_npc_monster_zombieg</texture>
| + | |
− | <text>enc_mutant_zombieg_general</text>
| + | |
− | </article>
| + | |
− | </xml>
| + | |
− | | + | |
− | И в связанный с ним файл string_table_enc_mutants.xml в папке gamedata\config\text\rus\ добавляем:
| + | |
− | | + | |
− | <xml>
| + | |
− | <string id="Zombie">
| + | |
− | <text>Зомби, гражданский</text>
| + | |
− | </string>
| + | |
− | <string id="Zombieg">
| + | |
− | <text>Зомби-призрак, гражданский</text>
| + | |
− | </string>
| + | |
− | <string id="enc_mutant_zombieg_general">
| + | |
− | <text>Зомби-привидение отличается от обычного зомби лишь тем, что
| + | |
− | воздействие Выжигателя мозгов полностью разрушило не только структуру личности, но и
| + | |
− | тело, поэтому зомби-призрак несколько более живуч по сравнению с обычным зомби.</text>
| + | |
− | </string>
| + | |
− | <string id="enc_mutant_zombie_general">
| + | |
− | <text>Воздействие Выжигателя мозгов полностью разрушает структуру личности,
| + | |
− | оставляя только телесную оболочку.\n\n Побродив немного по Зоне, лишённые разума тела
| + | |
− | начинают превращаться в настоящих зомби. Из рефлексов у них остаются лишь самые примитивные,
| + | |
− | оружие и экипировка скоро приходят в негодность. В результате зомби становятся собой ни чем
| + | |
− | иным, как медлительными полутрупами, которых наличествуют лишь два эффективных раздражителя:
| + | |
− | еда и сон. Зомби совершенно неразборчивы в выборе пищи и питья, поэтому их тела буквально
| + | |
− | пропитаны радиацией и токсинами. Как правило, эти существа бесцельно бродят по Зоне или,
| + | |
− | словно трупы, валяются внутри заброшенных построек. Однако, лишь только зомби почует близкое
| + | |
− | присутствие живого человека, он сразу же пытается атаковать. Умудрённые опытом сталкеры
| + | |
− | стараются обходить эти неуклюжие опустошённые оболочки.</text>
| + | |
− | </string>
| + | |
− | </xml>
| + | |
− | | + | |
− | Копируем сюда же файл stable_statistic_caption.xml и изменяем в нем 3 строчки:
| + | |
− | | + | |
− | <xml>
| + | |
− | <string id="zombie_normal">
| + | |
− | <text>зомбированный, гражданский</text>
| + | |
− | </string>
| + | |
− | <string id="zombie_strong">
| + | |
− | <text>зомби-призрак, гражданский</text>
| + | |
− | </string>
| + | |
− | <string id="zombie_weak">
| + | |
− | <text>зомби, гражданский</text>
| + | |
− | </string>
| + | |
− | </xml>
| + | |
− | | + | |
− | Сохраняем и закрываем.
| + | |
− | | + | |
− | '''7.''' И последнее – добавим иконки. Скажу сразу, воспользовался готовым файлом, уже содержащим иконки зомби и других «восстановленных монстров» (спасибо Fr3nzy). Поэтому просто скопируйте файл ui_npc_monster.dds из архива в папку gamedata\textures\ui\, а файл ui_npc_monster.xml – в папку gamedata\config\ui\. Если вы хотите сделать собственные - прочитайте урок по [[Изменение текстур (BAC9-FLCL)|изменению текстур]].
| + | |
− | | + | |
− | Вкратце, что описывает файл ui_npc_monster.xml: в нем задаются координаты иконок, расположенных в файле ui_npc_monster.dds, применительно к каждому типу монстров в игре.
| + | |
− | | + | |
− | Заключительный штрих. Откройте файл m_zombie.ltx и в первой секции замените строку
| + | |
− | | + | |
− | <ini>
| + | |
− | icon = ui_npc_monster_kontroler
| + | |
− | </ini>
| + | |
− | | + | |
− | на:
| + | |
− | | + | |
− | <ini>
| + | |
− | icon = ui_npc_monster_zombie
| + | |
− | </ini>
| + | |
− | | + | |
− | В секцию [zombie_ghost] добавьте строку:
| + | |
− | | + | |
− | <ini>
| + | |
− | icon = ui_npc_monster_zombieg
| + | |
− | </ini>
| + | |
− | | + | |
− | Сохраняйте изменения. Всё.
| + | |
− | | + | |
− | Вот [http://data.cod.ru/1290894794 готовые файлы примера].
| + | |
− | Удачи и спасибо за внимание :)
| + | |
− | | + | |
− | ==Спавн NPC==
| + | |
− | | + | |
− | <span style="color: gray">Эта часть статьи написана [[Участник:Arhet|Arhet]] и создана на примере того, как в SRP Mod были созданы NPC группировки "Грех".</span> | + | |
− | | + | |
− | Задействуем файлы:
| + | |
− | | + | |
− | * gamedata\config\gameplay\character_desc_escape.xml
| + | |
− | * gamedata\config\gameplay\npc_profile.ltx
| + | |
− | * gamedata\config\creatures\spawn_sections.ltx
| + | |
− | | + | |
− | Начнем с ''character_desc_escape.xml''. Описание, что значит каждая строка, писать не буду, так как все до меня уже сделано.
| + | |
− | | + | |
− | Тут создадим нового персонажа:
| + | |
− | | + | |
− | <xml>
| + | |
− | <specific_character id="esc_dark_stalker_1" team_default = "1">
| + | |
− | <name>GENERATE_NAME_bandit</name>
| + | |
− | <icon>ui_npc_dark_1</icon>
| + | |
− | <map_icon x="0" y="0"></map_icon>
| + | |
− | <bio>sim_stalker_novice_bio</bio>
| + | |
− | | + | |
− | <class>esc_dark_stalker_01</class> - вот тут наш новый класс кстати.
| + | |
− | <community>dark_stalker</community> <terrain_sect>stalker_terrain</terrain_sect>
| + | |
− | <money min="200" max="600" infinitive="0"></money>
| + | |
− | | + | |
− | <rank>198</rank>
| + | |
− | <reputation>-24</reputation>
| + | |
− | | + | |
− | <visual>actors\dark_stalker\dark_stalker_1</visual>
| + | |
− | <snd_config>characters_voice\human_01\monolith\</snd_config>
| + | |
− | <crouch_type>-1</crouch_type>
| + | |
− | <panic_treshold>0</panic_treshold>
| + | |
− | <supplies>
| + | |
− | [spawn] \n
| + | |
− | wpn_dark_colt1911 \n
| + | |
− | ammo_11.43x23_hydro \n
| + | |
− | #include "gameplay\character_items.xml" \n
| + | |
− | #include "gameplay\character_drugs.xml" \n
| + | |
− | #include "gameplay\character_food.xml"
| + | |
− | </supplies>
| + | |
− | | + | |
− | #include "gameplay\character_criticals_3.xml"
| + | |
− | | + | |
− | <start_dialog>dm_hello_dialog</start_dialog>
| + | |
− | <actor_dialog>dm_cool_info_dialog</actor_dialog>
| + | |
− | </specific_character>
| + | |
− | </xml>
| + | |
− | | + | |
− | Впишем наш код после какого-нибудь </specific_character>.
| + | |
− | | + | |
− | Теперь идем в ''npc_profile.xml'' и туда вгоняем:
| + | |
− | | + | |
− | <xml>
| + | |
− | <character id="esc_dark_stalker_1">
| + | |
− | <class>esc_dark_stalker_01</class>
| + | |
− | <specific_character>esc_dark_stalker_1</specific_character>
| + | |
− | </character>
| + | |
− | </xml>
| + | |
− | | + | |
− | Теперь надо заняться ''spawn_sections.ltx''. Скрипт будет «брать NPC» как раз из этого файла. Пишем туда:
| + | |
− | | + | |
− | * [esc_dark_stalker_1]:stalker – имя секции для скрипта..
| + | |
− | * $spawn = "respawn\esc_dark_stalker_1"
| + | |
− | * character_profile = esc_dark_stalker_1 – ссылка на описание нашего NPC
| + | |
− | * spec_rank = regular – спец ранг
| + | |
− | * community = dark_stalker – группировка.
| + | |
− | | + | |
− | Теперь берем любой скрипт спавна NPC, вгоняем туда имя секции из spawn_sections.ltx и ву-а-ля.
| + | |
− | | + | |
− | Ну, к примеру, создаем свой файл со скриптом спавна, назовем его - spaw_new_npc.script
| + | |
− | и запишем туда вот такую функцию (взял из статьи):
| + | |
− | | + | |
− | <lua>
| + | |
− | function spaw_n_n() --тут задается сама функция, которая в последующем будет активирована, к примеру с помощью диалога
| + | |
− | local a = vector() -- db.actor:position() -- тип переменной, которая будет задействована в спавне, вместо кооржинат будет писаться a
| + | |
− | a.x = -220.21
| + | |
− | a.y = -19.93
| + | |
− | a.z = -158.98
| + | |
− | alife():create("wpn_ak47",a,33447,47,65535) -- здесь сам спавн объекта, a - тип переменной которую мы указали выше
| + | |
− | end
| + | |
− | </lua>
| + | |
− | | + | |
− | Вот и весь скрипт! Теперь надо его активировать, ну к примеру через диалог, после диалога вставляем:
| + | |
− | | + | |
− | <xml>
| + | |
− | <action>spaw_new_npc.spaw_n_n</action>
| + | |
− | </xml>
| + | |
− | | + | |
− | распишу, что значит:
| + | |
− | | + | |
− | <xml>
| + | |
− | <action>названиескрипта.функциякоторуюнеобходимоактивировать</action>
| + | |
− | </xml>
| + | |
− | | + | |
− | <span style="color: gray">Например:
| + | |
− | | + | |
− | <xml>
| + | |
− | <game_dialogs>
| + | |
− | ………
| + | |
− | ………
| + | |
− | ………
| + | |
− | <dialog id="lokationname_testdialog_start">
| + | |
− | <phrase_list>
| + | |
− | <phrase id="1">
| + | |
− | <text>locationname_testdialog_start_1</text> <!-- ссылка на файл с текстом фразы -->
| + | |
− | <action>test_script.testfunction</action> <!-- ссылка на функцию testfunction скрипта test_script -->
| + | |
− | </phrase>
| + | |
− | </phrase_list>
| + | |
− | </dialog>
| + | |
− | ………
| + | |
− | ………
| + | |
− | ………
| + | |
− | </game_dialogs>
| + | |
− | </xml>
| + | |
− | [[Участник:RedPython|RedPython]] 16:09, 10 октября 2010 (UTC)
| + | |
− | </span>
| + | |
− | | + | |
− | Тока забыли что данному НПС будет присвоенная дефолтовая логика (т.е. тупо хожу куда сам не знаю) забыли упомянуть про (ххх - лока):<br>
| + | |
− | ххх gulag.script (действия НПС! Где можно: где можно присвоить статус кампера; волкера; и.д.т)<br>
| + | |
− | ххх gulag.ltx (дублер логики т.е. дублирует кратко действия НПС)
| + | |
− | | + | |
− | ==Авторы==
| + | |
− | | + | |
− | Статья создана:
| + | |
− | | + | |
− | * [[Участник:XStream|xStream]]
| + | |
− | * [[Участник:RekLatS|OffBar]]
| + | |
− | * [[Участник:Fr3nzy|Fr3nzy]]
| + | |
− | * [[Участник:Imp|Imp]]
| + | |
− | * [[Участник:Arhet|Arhet]]
| + | |
− | | + | |
− | Статья исправлена:
| + | |
− | * [[Участник:Rekongstor|Rekongstor]]
| + | |
− | | + | |
− | В статью добавили:
| + | |
− | * [[Участник:Byurrer]]
| + | |
− | | + | |
− | [[Категория:Скрипты]]
| + | |
Наш сервис предоставляет настоящие лайки на фотографии заказчиков, которые готовы платить за качество.
Именно для этого мы и набираем удалённых сотрудников, которые будут выполнять работу, то есть ставить лайки и получить за это деньги.
Чтобы стать нашим удалённым сотрудником и начать ставить лайки, зарабатывая при этом 45 рублей за 1 поставленный лайк,
достаточно просто зарегистрироваться на нашем сервисе. > like.zarplatt.ru <