Спавн через скрипт

Спавн через скриптВ скриптах есть одна единственная функция, отвечающая за спавн объектов:

alife():create(section, position, levelvertex, gamevertex)

Строго говоря, их две: create create_ammo но различия между ними не существенны. Imp 22:45, 23 июля 2007 (EEST)

Первый параметр — секция в конфигурациях, описывающая объект, например «bolt»,»med_kit» — это простые секции, простых объектов а есть объекты, которые переходят в онлайн/оффлайн, это неписи, монстры и так далее, например mil_killer_respawn_2 — спавнится снайпер группировки киллеров.

С позицией, думаю объяснять не надо, только существует нюанс — высота это Y, а не Z. Задать позицию можно такой конструкцией vector():set(x, y,z), где x, y и z — координаты точки на уровне, где спавним объект.

Дальше сложнее, так как сам толком сформулировать не могу.

Начнем от простого к сложному. На каждом уровне много объектов, все объекты состоят из полигонов, у каждого полигона есть вершины – вертексы.

Именно они и должны здесь указываться, зачем — не особо понимаю, скорее всего для точного позиционирования объекта. Например, можно получить вертекс ближайший к актору — db. actor:level_vertex()

Дальше идет гораздо более интересный параметр game_vertex, это почти то же самое, что и level_vertex, но (!) это глобальные величины! Если level_vertex считается для уровня, то game_vertex — для всей игры, и нужен он для того, чтобы указать на какой карте спавнить объект (более вразумительного объяснения я не нашел).

Соответственно, чтобы заспавнить что-нибудь на другой карте, достаточно указать game_vertex в четвертом параметре Например:

db. actor:game_vertex()

Итак, чтобы, например, заспавнить болт под ногами актора, пишем:

alife():create(«bolt»,db. actor():position(),1,db. actor:game_vertex())

Почему 1, а не level_vertex? Проверено — разницы особой нет, какой level_vertex, хотя в некоторых случаях надо прописывать валидный вертекс, а то предмет может просто заспавнится не там, где планировалось. Но по большей части все проходит нормально и с единицей. (Игнорирование level_vertex может приводить к проваливанию произведенных предметов/персонажей под землю.) А вот game_vertex решает все — он указывает на каком уровне спавнить предмет, поэтому его надо указывать. Теоретически можно просто найти для каждого уровня по одному game_vertex’у и использовать их в скриптах. На самом деле game_vertex показывает какой фрагмент карты используется (вся карта разбита на кусочки имеющие сквозную нумерацию по всем уровням и game_vertex выбирает нужный) соответсвенно неправильное использование черевато.

Кроме того — есть еще один параметр — ID объекта, если указать ID NPC или актора — то предмет заспавнится у него в инвентаре.

Пример (спавним артефакт Медуза в инвентаре у актора):

alife():create(«af_medusa», db. actor():position(), 1, db. actor:game_vertex(), db. actor:id())

Функция спавна возвращает серверный объект, то есть ни NPC, ни монстра ни что-либо еще.

Серверный обьект позволяет свеже созданного NPC или тайник затарить разными рулезами/артефактами. Например, вот так создадим перед входом к Сидоровичу долговца и засунем в него пачку патронов:

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) — число патронов

Кстати, create_ammo — практически тоже самое, что и create, разница в том, что create_ammo предназначена специально для спавна патронов и позволяет создавать неполные пачки патронов. Возможно есть еще какие-то отличия. Стоит учесть, что сами авторы игры спавнят патроны исключительно через create_ammo. Imp 22:38, 23 июля 2007 (EEST)

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

(alife():object(id))

Его можно использовать, чтобы поставить метку, например, но я его лично использую для других целей — спавн сложных объектов, конкретно – NPC.

Например надо решить следующую задачу — надо создать наемника, сменить ему группировку и изменить его инвентарь, ну и в нагрузку — сделать другом для игрока.

В определенный момент заспавненый объект переходит онлайн, в этот момент вызывается callback — net_spawn.

Что мы делаем? Сверяем ID онлайн объекта с сохраненным ID!

Если они совпадают, например так:

if obj:id()==saved_id then.

Важно то, что у серверного объекта ID — это параметр, а у онлайнового объекта ID получается с помощью функции. Это важно, а то можно прогореть.

Итак, мы поймали нашего киллера по ID.

Далее все очень просто — вызываем команды для спавна гаусса и патронов к нему в инвентаре NPC (см. выше), меняем группировку специальной функцией, и делаем его другом.

Зачем такие сложности? Просто в оффлайне NPC как бы не существует, есть только косвенное упоминание о нем, и, плюс, все эти функции работают именно с объектом типа «NPC», а не с серверными объектами.

Практика (часть 1)

1. Чтобы не повторяться в описании создания нового квеста, просто изучите статью по созданию квестов от Fr3nzy – лучшей статьи на эту тему я просто не видел 🙂 Мы просто свяжем все воедино и научимся спавнить объекты из скрипта.

Небольшое отступление:

Почему предпочтительнее делать спавн скриптом, а не через тот же xrSpawner? Программа xrSpawner, при всех своих достоинствах, обладает одним недостатком, а именно – она делает спавн через файл all. spawn, что приводит к:

Невозможности совместить два мода, такой спавн использующих

Необходимости каждый раз начинать новую игру

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

Итак, определимся с квестом.

Задача: после разговора с Сидоровичем спавним зомби на территории фабрики в первой локации. Для того, чтобы не повредить оригинальный сюжет игры, задание будет выдаваться после прохождения квеста с флешкой Шустрого, так как появись там зомби одновременно с бандитами и Шустрым. я думаю, исход боя предрешен 🙂

Реализация: Постараюсь описать все действия максимально подробно, буквально по шагам. Первым делом запустите игру 🙂

В консоли введите команду:

rs_stats on или rs_stats 1

Тем самым мы включаем вывод информации на экран. Далее вводим еще одну команду:

demo_record 1

И «летим» на фабрику. Нам нужно выбрать место для спавна объектов и данный режим как нельзя лучше подходит для реализации задуманного. Помещаем камеру в точке предполагаемого спавна и записываем координаты — у меня получились 115, -6, -16.

Для выхода из режима demo_record нажимаем Esc, в консоли пишем rs_stats off или rs_stats 0 (убираем вывод информации).

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

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 В результате не нужно эксперементировать мы сразу получаем все, в том числе и level_vertex и game_vertex. Imp 22:38, 23 июля 2007 (EEST) Выходим из игры, идем в папку с установленной игрой и создаем каталог 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 Вернем в игру их всех 🙂 Уже имеются секции: [zombie_weak]:m_zombie_e, [zombie_normal]:m_zombie_e, [zombie_strong]:m_zombie_e и [zombie_immortal]:zombie_strong. Два последних типа используют одну и ту же модель zombi_trup. ogf, хм. непорядок, исправляем. Последняя секция выглядит теперь так: [zombie_immortal]:zombie_strong $spawn = «monsters\zombies\zombie_immortal»

visual = monsters\zombi\zombi_trup_2

panic_threshold = 0.05

Добавим пятую модель.

Для этого в конце файла создадим секцию:

[zombie_ghost]:zombie_strong

Это означает, что наш пятый зомби наследует все параметры zombie_strong, мы добавим лишь визуальное представление.

Пишем дальше:

$spawn = «monsters\zombies\zombie_ghost»

visual = monsters\zombi\zombi_1_ghost

Все. Сохраняем изменения и закрываем файл.

2. Пишем скрипт спавна. В папке gamedata создаем новую папку scripts, в ней создаем новый текстовый документ и называем его esc_zombie. script.

Отступление третье:

При написании статьи использовался оригинальный скрипт zombie_story. script из horror-mod’а. Концепция спавна перенесена практически без изменений, поэтому на авторство этого способа спавна я никоим образом не претендую 🙂

Итак, открываем наш пустой файл на редактирование, первой строкой объявляем переменную, в которой хранятся наши зомби:

Далее пишем функцию:

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

function zomby_story_1( actor, npc )

— десять зомби на фабрике (Кордон)

local spawn_point = vector():set( 115, -6, -16 ) — здесь указываем координаты,

выбранные нами для спавна, когда «летали» камерой 🙂

spawn_zombies( spawn_point, 10 ) — собственно вызов предыдущей функции

с передачей ей координат и количества объектов

end

Все. Сохраняем и закрываем файл.

Продолжаем разговор 🙂

Для того, чтобы игра не вылетала после того, как мы добавили новый тип монстров, их нужно добавить в файл xr_statistic. script. Итак, скопируем этот файл из папки игры scripts в нашу папку к файлу esc_zombie. script и откроем на редактирование.

Добавим в local killCountProps к монстрам строчку:

zombie_weak = 1, zombie_normal = 2, zombie_str 3

В local sect_alias строчку:

zombie_weak = «zombie_weak», zombie_normal = «zombie_normal», zombie_str «zombie_strong»

А ниже в monster_classes строчку:

[clsid. zombie_s ] = «zombie»

В функцию getNpcType(npc) добавляем конструкцию:

elseif npc:character_community() == «zombie» then

community = «zombie»

Сохраняем изменения и закрываем файл.

Все будет работать на ура, пока мы не попробуем обыскать убитого зомби. Как только мы это сделаем, игра вылетит с примерно такой ошибкой.

Expression. fatal error

Function. CInifile::r_string

File. D:\xray-svn\xrCore\Xr_ini. cpp

Line. 351

Description :

Arguments. Can’t find variable icon in [zombie_weak]

Все верно – игра не знает какую иконку нам показывать для зомби. Иконки монстров хранятся в файле ui_npc_monster. dds. Здесь есть два варианта:

Если дружите с Фотошопом, отредактировать этот файл (нарисовать, добавить иконки);

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

Вернемся к файлу m_zombie. ltx и в секцию [m_zombie_e]:monster_base впишем параметр

icon = ui_npc_monster_kontroler

Все. Вылетов не будет.

3. Тема данной статьи не предусматривает подробного описания того, как сделать новый диалог. В начале статьи я упомянул источник, где можно найти исчерпывающую информацию по созданию диалогов, могу также привести в пример статью по созданию диалогов от BAC9-FLCL.

Нам нужно просто проверить работоспособность скриптового спавна, поэтому я приведу просто собственно сам измененный диалог из файла dialogs_escape. xml:

………

escape_trader_talk_info_999

как писать скрипты

как настроить скрипт

как установить скрипт на сайт

This entry was posted in Как через скрипт and tagged , , , . Bookmark the <a href="http://iprowebber.ru/spavn-cherez-skript/" title="Permalink to Спавн через скрипт" rel="bookmark">permalink</a>.

Comments are closed.