Новый торговец
tom-m15
09 сент. 2009
Болезненная тема для многих начинающих модмейкеров. Для создания нового тороговца требуется постигать навыки работы со спавн-файлом. Для создания торговца придётся запастись кое-какими утилитами:
acdc от bardak скачать
ActivePerl 5.8.8 для работы программы acdc скачать
Практика
Создание непися и профиля
И так. Сперва мы создаём профиль непися. Например, в файле character_desc_escape.xml по адресу gamedata\config\gameplay\ Можно создать отдельный файл для наших неписей, это упрощает совмещение модов. В файле character_desc_escape.xml, в самом низу, перед тегом </xml> пишем профиль нового непися:
Ввод в симуляцию
Непись создан. Теперь надо вводить его в симуляцию. Открываем файл gamedata\config\creatures\spawn_sections.ltx и прописываем в конце:
Спавн торговца через all.spawn файл
Дальше, самое нудное - спавн. Спасибо Arhet'y за пример. Используя прогу acdc от bardak'a декомпилим all.spawn, создав батник разбора спавна (без active perl толку от проги бардака нуль - просто не запустится) и в понравившемся месте делаем запись с уникальным номером. Я заспавнил на Кордоне:
Спавн файл еще рано собирать!
Логика торговца
Далее, создаём файл конфиг торговца, который указали в спавне - gamedata\config\scripts\esc_voron.ltx и пишем в нём:
Заходим в игру, ищем нужное нам место (ногами), жмём из меню кнопку CREDITS и мы услышим звуковой сигнал, после чего выходим в игру из меню, и в строке сообщений высветиться вся инфа. Всё - F12 или на бумажку списываем полученные координаты.
Создаём вейпоинты и лукпоинты
И так, мы сняли координаты мест, где хотим видеть торговца и где мы хотим, чтобы он ходил - теперь в разобранном all.spawn ищите файл way_*левел*.ltx и туда пишем данные. Я приведу пример свой, опять таки. В файле way_l01_escape.ltx пишем:
После всего этого собираем all.spawn батником (что писать в батниках для сбора и разбора спавна - в файле help.txt в папке с программой), закидываем новый файл спавна в gamedata/spawn и стартуем новую игру.
Присваеваем торговлю уже имеющемуся неписю
можно и описанным способом,но иногда требуется присвоить торговлю к уже имеющимся неписям.Будем делать торговцем кого-нибудь из уже имеющихся...Кого,кого,кого... Как обычно Волка(у меня две подопотных "крысы"-Сидорович и Волк,а так как Сид уже им является,выбор очевиден
Ну чтож приступим.Необходимо создать "файл торговли" типа "trade_....ltx". Можно прописать его самому(как это делать я объяснять не буду,т.к. и до меня все это сделано не один раз
,можно скопировать любой другой...я скопировал "trade_freedom.ltx" и переименовал его в "trade_wolf" и удалил все прикондишны с информацией на разрешение торговли.Теперь нужно сослаться на его.Делается это в файле логики,тобиш в "gulag_escape.ltx"(почему в эскейп,думаю понятно, наш Волк находится на нем-Кордоне
.Открываем файл и ищем строки: ....
-------------------------------------------------------------------------------------------------
-- ESCAPE LAGER
-------------------------------------------------------------------------------------------------
Волк
[logic@esc_lager_volk] active = walker@esc_lager_volk_walker1 on_death = death@wolf
[walker@esc_lager_volk_walker1] path_walk = wolf_walk path_look = wolf_look meet = meet@wolf on_actor_dist_le = 23| {+tutorial_wounded_start -esc_kill_bandits_quest_kill} remark@esc_lager_volk1 on_actor_dist_le_nvis = 5| walker@esc_lager_volk_walker2 danger = danger_condition@shustryi
[remark@esc_lager_volk1] anim = hello_wpn snd = esc_wolf_say_thanks target = actor on_signal = sound_end| walker@esc_lager_volk_walker2 on_actor_dist_le_nvis = 5| walker@esc_lager_volk_walker2 danger = danger_condition@shustryi ..... Теперь сошлемся на наш трад-в секцию "[logic@esc_lager_volk]" добавим строки:
trade = misc\trade_wolf.ltx inv_max_weight = 10000
То есть должно получится следующее:
-------------------------------------------------------------------------------------------------
-- ESCAPE LAGER
-------------------------------------------------------------------------------------------------
Волк
[logic@esc_lager_volk]
active = walker@esc_lager_volk_walker1
on_death = death@wolf
trade = misc\trade_wolf.ltx
inv_max_weight = 10000
... Традом мы ссылаемся на наш "торговый файл",а вот следующей строкой увеличиваем переносимый вес,поскольку он и у неписей ограничен
Осталось только дать нашему "новороженному" торговцу-Волку побольше денег...Делаем это точно также как описано,но различие в том,что мы редактируем секцию Волка в "character_desc_escape.xml" Я еще и удалил строку "#include "gameplay\character_criticals_4.xml"" с ограничением по весу,но правда на всякий случай,поскольку не проверял,работает ли с ним=) На этом все,заходим в игру и наслаждаемся собственным творением
P.S.-Упс,работает,но как-то неправильно
...у торговца оказывается нет поддержки перемещения
Поэтому ГСЦ всех торгошей и биндят не сталкером,а монстром
Заработало только когда я в бинде сталкера прописал:
function actor_binder:reinit() object_binder.reinit(self)
local npc_id = self.object:id()
db.storage[npc_id] = { }
self.st = db.storage[npc_id] self.st.pstor = nil
self.next_restrictors_update_time = -10000
self.object:set_callback(callback.inventory_info, self.info_callback, self) self.object:set_callback(callback.article_info, self.article_callback, self) self.object:set_callback(callback.on_item_take, self.on_item_take, self) self.object:set_callback(callback.on_item_drop, self.on_item_drop, self) self.object:set_callback(callback.trade_sell_buy_item, self.on_trade, self) -- for game stats --self.object:set_callback(callback.actor_sleep, self.sleep_callback, self) self.object:set_callback(callback.task_state, self.task_callback, self) --self.object:set_callback(callback.map_location_added, self.map_location_added_callback, self) self.object:set_callback(callback.level_border_enter, self.level_border_enter, self) self.object:set_callback(callback.level_border_exit, self.level_border_exit, self) self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self)
вот мои строки
if self.object:clsid() ~= clsid.script_trader then self.object:set_patrol_extrapolate_callback(bind_monster.generic_object_binder.e
xtrapolate_callback, self) end
db.storage[self.object:id()] = { }
self.st = db.storage[self.object:id()]
self.object:set_callback(callback.patrol_path_in_point, self.waypoint_callback, self) self.object:set_callback(callback.hit, self.hit_callback, self) self.object:set_callback(callback.death, self.death_callback, self) end
Заместо старого.Все будет работать на УРА,с одним огрехом-Волк не будет отмечатся как цель при задании поговорить с Волком перед АТП,но думаю это не столь важно
Ну и еще без ствола будет ходить, но если будет атакован,то пушка появится "из широких штанин=-)" Волка и он будет из нее пытаться вас нашпиговать свинцом
Пост скриптум,дубль два
...Теоритически,если строки с калбеками из обычной секции сталкера прописать в мою,то наш традер(в данном случае Волк) будет неким гибридом,сочетающим свойства как и НПС,так и уникальных торговцев,попробуйте,должно работать=-)
Авторы
Статья Орион.
При помощи (косвенной) Arhet.
Дополнение Костя.н.ы.ч.
acdc от bardak скачать
ActivePerl 5.8.8 для работы программы acdc скачать
Практика
Создание непися и профиля
И так. Сперва мы создаём профиль непися. Например, в файле character_desc_escape.xml по адресу gamedata\config\gameplay\ Можно создать отдельный файл для наших неписей, это упрощает совмещение модов. В файле character_desc_escape.xml, в самом низу, перед тегом </xml> пишем профиль нового непися:
<specific_character id="esc_dark_stalker_voron" no_random = "1"> ;важно при создании торговца, указать параметр no_random = "1" <name>Ворон</name> <icon>ui_npc_dark_voron</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> <money min="500000" max="500000" infinitive="1"></money> ;в поле денег, надо поставить бессконечные деньги - infinitive="1" ;иначе вы сможете продать неписю товаров исключительно на указанную сумму. <rank>1000</rank> <reputation>-553</reputation> <visual>actors\dark_stalker\dark_stalker_voron</visual> ;ссылка на файл-модель персонажа без окончания .ogf <snd_config>characters_voice\human_01\monolith\</snd_config> <crouch_type>-1</crouch_type> <panic_treshold>0</panic_treshold> <supplies> [spawn] \n wpn_gauss \n ammo_gauss \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>hello_dialog_dark_stalker</start_dialog> <actor_dialog>dm_cool_info_dialog</actor_dialog> <actor_dialog>dm_help_wounded_medkit_dialog</actor_dialog> <actor_dialog>join_dark</actor_dialog> </specific_character>Профиль создан, пара стандартных диалогов, взятых у любого другого профиля, дописать не составит труда. Я ничего не менял в своём коде. Лезем в npc_profile.xml, который находится в той же папке. Где-нить внизу делаем запись:
<character id="esc_dark_stalker_voron"> <class>esc_dark_stalker_01</class> -- настраивает респавнер на класс персонажа для спавна разных моделей. ;т.к. мы спавним уникального непися, класс можно скопировать у любого другого непися или написать новый, уникальный класс. <specific_character>esc_dark_stalker_voron</specific_character> -- ссылка на профиль нашего непися. </character>
Ввод в симуляцию
Непись создан. Теперь надо вводить его в симуляцию. Открываем файл gamedata\config\creatures\spawn_sections.ltx и прописываем в конце:
[esc_dark_stalker_voron]:stalker_trader - дописать суффикс торговца... хотя у меня и без него всё работало =) $spawn = "respawn\esc_dark_stalker_voron" - опция спавна для Левел Едитора character_profile = esc_dark_stalker_voron - профиль непися, записанный в npc_profile.xml spec_rank = regular community = dark_stalker - группировка
Спавн торговца через all.spawn файл
Дальше, самое нудное - спавн. Спасибо Arhet'y за пример. Используя прогу acdc от bardak'a декомпилим all.spawn, создав батник разбора спавна (без active perl толку от проги бардака нуль - просто не запустится) и в понравившемся месте делаем запись с уникальным номером. Я заспавнил на Кордоне:
[8796] ; cse_abstract properties section_name = stalker_trader -- метка, что сталкер является торговцем name = dark_stalker_voron -- имя любое, вроде бы; где оно используется не знаю position = -215.67399597168,-20.403390884355,-151.03227233887 -- местоположение на игровой карте direction = 0.0445535257458687,-0.000645029998850077,0.0144814234226942 ; cse_alife_trader_abstract properties character_profile = esc_dark_stalker_voron ; cse_alife_object properties game_vertex_id = 61 -- геймвертекс, без него спавнер не будет знать, на какой именно карте и в какой её части спавнить объект distance = 3.5 level_vertex_id = 42599 -- левелвертекс, без него спавнер не будет знать, в именно какой части карты спавнить объект object_flags = 0xfffffffb custom_data = <<END [logic] cfg = scripts\esc_voron.ltx -- конфиг с логикой [smart_terrains] none = true -- смарт террейн; если создаёте статического торговца - лучше не выставлять смарт террейн ;если хотите бродягу - пишите по аналогии с другими неписями или создавайте свой смарт террейн, куда и определяйте непися [spawn] wpn_gauss -- спавним в инвентаре всё, что хотим, в продажу оно не пойдёт END story_id = 9958 - уникальный стори_ид для меток на карте ; cse_visual properties visual_name = actors\dark_stalker\dark_stalker_voron -- внешний вид, указать путь к .ogf модели, без окончания формата файла! ; cse_alife_creature_abstract properties g_team = 0 g_squad = 0 g_group = 0 health = 2 dynamic_out_restrictions = dynamic_in_restrictions = upd:health = 2 upd:timestamp = 0 upd:creature_flags = 0 upd:position = -215.67399597168,-20.403390884355,-151.03227233887 -- те же координаты, что и в секции position upd:o_model = 0 upd:o_torso = 0,0,0 upd:g_team = 0 upd:g_squad = 0 upd:g_group = 0 ; cse_alife_monster_abstract properties upd:next_game_vertex_id = 65535 upd:prev_game_vertex_id = 65535 upd:distance_from_point = 0 upd:distance_to_point = 0 ; cse_alife_human_abstract properties predicate5 = 2,2,1,2,0 predicate4 = 2,2,1,2 ; cse_ph_skeleton properties upd:start_dialog = ; se_stalker properties
Спавн файл еще рано собирать!
Логика торговца
Далее, создаём файл конфиг торговца, который указали в спавне - gamedata\config\scripts\esc_voron.ltx и пишем в нём:
[logic] active = walker trade = misc\trade_voron.ltx -- файл торговли, создаётся по аналогии с существующими trader_flags = 0 - флаг трейдера inv_max_weight = 10000 -- вес инвентаря торговца on_death = death [walker] path_walk = esc_sin_voron_walk -- привязка вейпоинта, чтобы трейдер стоял на месте или двигался по определённому курсу path_look = esc_sin_voron_look -- куда будет смотреть непись meet = meet -- параметры реакции непися на встречу с актором [meet] use = true use_wpn = true -- перезаряжает оружие meet_talk_enabled = trueТеперь лезем за скриптом от бардака и снимаем координаты местоположения нашего непися. У кого нету скрипта, копируем в gamedata/scripts/ui_main_menu.script этот скрипт:
function main_menu:OnButton_credits_clicked() 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
Заходим в игру, ищем нужное нам место (ногами), жмём из меню кнопку CREDITS и мы услышим звуковой сигнал, после чего выходим в игру из меню, и в строке сообщений высветиться вся инфа. Всё - F12 или на бумажку списываем полученные координаты.
Создаём вейпоинты и лукпоинты
И так, мы сняли координаты мест, где хотим видеть торговца и где мы хотим, чтобы он ходил - теперь в разобранном all.spawn ищите файл way_*левел*.ltx и туда пишем данные. Я приведу пример свой, опять таки. В файле way_l01_escape.ltx пишем:
[esc_sin_voron_look] -- имя, которые мы записали в ''gamedata\config\scripts\esc_voron.ltx'' points = p0,p1 p0:name = wp00 p0:flags = 0x1 p0:position = -205.306793212891,-20.4855155944824,-150.415893554688 p0:game_vertex_id = 46 p0:level_vertex_id = 54218 p1:name = wp01 p1:flags = 0x1 p1:position = -207.645278930664,-20.2700958251953,-146.980590820313 p1:game_vertex_id = 61 p1:level_vertex_id = 45276 [esc_sin_voron_walk] -- имя, которые мы записали в ''gamedata\config\scripts\esc_voron.ltx'' points = p0 p0:name = wp00 p0:flags = 0x1 p0:position = -215.67399597168,-20.403390884355,-151.03227233887 p0:game_vertex_id = 47 p0:level_vertex_id = 37503Если нужно создать несколько вейпоинтов - смотрите по аналогии с уже существующими.
После всего этого собираем all.spawn батником (что писать в батниках для сбора и разбора спавна - в файле help.txt в папке с программой), закидываем новый файл спавна в gamedata/spawn и стартуем новую игру.
Присваеваем торговлю уже имеющемуся неписю
можно и описанным способом,но иногда требуется присвоить торговлю к уже имеющимся неписям.Будем делать торговцем кого-нибудь из уже имеющихся...Кого,кого,кого... Как обычно Волка(у меня две подопотных "крысы"-Сидорович и Волк,а так как Сид уже им является,выбор очевиден



-------------------------------------------------------------------------------------------------
-- ESCAPE LAGER
-------------------------------------------------------------------------------------------------
Волк
[logic@esc_lager_volk] active = walker@esc_lager_volk_walker1 on_death = death@wolf
[walker@esc_lager_volk_walker1] path_walk = wolf_walk path_look = wolf_look meet = meet@wolf on_actor_dist_le = 23| {+tutorial_wounded_start -esc_kill_bandits_quest_kill} remark@esc_lager_volk1 on_actor_dist_le_nvis = 5| walker@esc_lager_volk_walker2 danger = danger_condition@shustryi
[remark@esc_lager_volk1] anim = hello_wpn snd = esc_wolf_say_thanks target = actor on_signal = sound_end| walker@esc_lager_volk_walker2 on_actor_dist_le_nvis = 5| walker@esc_lager_volk_walker2 danger = danger_condition@shustryi ..... Теперь сошлемся на наш трад-в секцию "[logic@esc_lager_volk]" добавим строки:
trade = misc\trade_wolf.ltx inv_max_weight = 10000
То есть должно получится следующее:
-------------------------------------------------------------------------------------------------
-- ESCAPE LAGER
-------------------------------------------------------------------------------------------------
Волк
[logic@esc_lager_volk]
active = walker@esc_lager_volk_walker1
on_death = death@wolf
trade = misc\trade_wolf.ltx
inv_max_weight = 10000
... Традом мы ссылаемся на наш "торговый файл",а вот следующей строкой увеличиваем переносимый вес,поскольку он и у неписей ограничен


P.S.-Упс,работает,но как-то неправильно



function actor_binder:reinit() object_binder.reinit(self)
local npc_id = self.object:id()
db.storage[npc_id] = { }
self.st = db.storage[npc_id] self.st.pstor = nil
self.next_restrictors_update_time = -10000
self.object:set_callback(callback.inventory_info, self.info_callback, self) self.object:set_callback(callback.article_info, self.article_callback, self) self.object:set_callback(callback.on_item_take, self.on_item_take, self) self.object:set_callback(callback.on_item_drop, self.on_item_drop, self) self.object:set_callback(callback.trade_sell_buy_item, self.on_trade, self) -- for game stats --self.object:set_callback(callback.actor_sleep, self.sleep_callback, self) self.object:set_callback(callback.task_state, self.task_callback, self) --self.object:set_callback(callback.map_location_added, self.map_location_added_callback, self) self.object:set_callback(callback.level_border_enter, self.level_border_enter, self) self.object:set_callback(callback.level_border_exit, self.level_border_exit, self) self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self)
вот мои строки
if self.object:clsid() ~= clsid.script_trader then self.object:set_patrol_extrapolate_callback(bind_monster.generic_object_binder.e
xtrapolate_callback, self) end
db.storage[self.object:id()] = { }
self.st = db.storage[self.object:id()]
self.object:set_callback(callback.patrol_path_in_point, self.waypoint_callback, self) self.object:set_callback(callback.hit, self.hit_callback, self) self.object:set_callback(callback.death, self.death_callback, self) end
Заместо старого.Все будет работать на УРА,с одним огрехом-Волк не будет отмечатся как цель при задании поговорить с Волком перед АТП,но думаю это не столь важно


Пост скриптум,дубль два

Авторы
Статья Орион.
При помощи (косвенной) Arhet.
Дополнение Костя.н.ы.ч.
Тифлон
27 июля 2010
РЕБЯТ ПОДСКАЖИТЕ ПОЖАЛУЙСТА КАК СДЕЛАТЬ НОВОГО НПС(СКРИПТ) КВЕСТОДАТЕЛЕМ? НУ НИ КАК НЕ ПОЛУЧАЕТСЯ((((((((((
Сообщение изменено: Lisaa (27 Июль 2010 - 14:35)
Сообщение изменено: Lisaa (27 Июль 2010 - 14:35)