• Страница 3 из 3
  • «
  • 1
  • 2
  • 3
Модератор форума: comador  
Форум настоящего сталкера » S.T.A.L.K.E.R. Тень Чернобыля » Теория модостроения » Маленькие уроки по модостроению
Маленькие уроки по модостроению
# 41
Понедельник, 01.08.2011, 08:48:41

Ранг: Разведчик
Сообщений: 367
Награды: 64
Репутация: 2435 Регистрация: 22.07.2011  

[spoiler]

Классы
Классы объектов используемых в Сталкере.
AMMO Патроны
ARTEFACT Артефакты
A_OG7B OG7B
A_VOG25 VOG25
A_M209 M209
AI_GRAPH ai\graph point
AI_SPGRP spawn_group_zone /spawn_group
AI_STL_S m_stalker.ltx
AI_STL [m_army_(боец)] [m_bandit_(боец)]
AI_CROW Ворона
AI_DOG_R [m_dog_e] (m_dog_.ltx)
AI_TRD_S Торговец (Бывший класс AI_TRADE)
AI_PHANT Фантомы монстров
AI_RAT_G Группа крыс
AI_RAT Крыса
C_HLCP_S Вертолёт
D_PDA КПК
D_SIMDET Детекторы
E_STLK equ_stalker Обмундирование людей(бывшие EQU_MLTR E_STLK)
EVENT ??tg_event
G_F1 Граната
G_RGD5 Граната
G_FAKE Fake Missiles and Grenades_____Свойства CustomRocket
G_RPG7 Ракета вертолета (weapons\rpg_7\wpn_rpg_7_grenade.ogf)
II_BOLT Болт
II_EXPLO Взрывоопасные объекты — бочки, канистры и т. д.
II_DOC item_document_01.ogf (Уникальное имя Documents)
II_ATTCH Аттачибл объекты, рация и пр.
II_FOOD Хавчик
II_BOTTL Водка
II_ANTIR Антирад
II_MEDKI Аптечки
II_BANDG Бинт
LVL_CHNG level_changer
NW_ATTCH custom_script_object (handradio было)
O_HLAMP lights_hanging_lamp
O_PHYS_S physic_object
O_SEARCH search_light
O_BRKBL breakable_object
O_ACTOR actor
O_INVBOX devices\inventory box
O_SWITCH trigger
C_HLCP_S helicopter
P_DSTRBL physic_destroyable_object
P_SKELET ph_skeleton_object
RE_SPAWN ai\respawn
SCRPTART Этот класс встречается у пары артефактов
SPECT spectator
SMRTTRRN smart_terrain
SCRPTCAR m_car
SCRIPTZN script_zone
SCRPTOBJ script_object
SM_BLOOD Кровосос
SM_BOARW Кабан
SM_BURER Бюрер
SM_CAT_S Кошка
SM_CHIMS Химера
SM_CONTR Контролер
SM_DOG_S Сепой пес
SM_FLESH Плоть
SM_IZLOM [m_fracture_e] (по идее излом)
SM_GIANT Псевдогигант
SM_POLTR Полтергейст
SM_P_DOG Псевдособака(Собака чернобыля)
SM_SNORK Снорк
SM_TUSHK Тушканчик (бывший AI_TUSH)
SM_ZOMBI Зомби
SPC_RS_S ai\space_restrictor
TORCH_S device_torch
W_MOUNTD wpn_pkm_trenoga.ogf
W_SILENC wpn_addon_silencer
W_GLAUNC wpn_addon_grenade_launcher
WP_WALTH Вальтер
WP_VINT Винторез
WP_VAL ВАЛ
WP_USP45 usp45
WP_SVU СВУ
WP_SHOTG Дробовики
WP_RPG7 РПГ7
WP_RG6 РГ6
WP_PM ПМ
WP_KNIFE Нож
WP_HPSA HPSA
WP_SVD СВД
WP_GROZA Гроза
WP_BM16 ВМ16
WP_BINOC Бинокль
WP_LR300 LR300
WP_AK74 АК74
WP_SCOPE Опт. Прицел
Аномалии и их классы
Z_TEAMBS zone_team_base
Z_MINCER
Z_GALANT
Z_AMEBA [zone_ameba]
Z_RADIO [zone_monolith] [zone_radioactive]
Z_NOGRAV [zone_no_gravity]
Z_MBALD [zone_campfire_mp_nolight] [zone_campfire_grill] [zone_flame] [zone_zhar] [zone_emi] [zone_flame_small]
[zone_mine_field] [zone_death] [zone_sarcofag] [zone_teleport] [zone_teleport_out]
Z_RUSTYH [zone_rusty_hair]
Z_ZONE [zone_teleport_monolith]
Z_TORRID [torrid_zone] [fireball_zone]
ZS_MINCE [zone_mincer] (статическая)
ZS_GALAN [zone_gravi_zone] (статическая)
ZS_MBALD [zone_buzz] [zone_mosquito_bald] [zone_witches_galantine] [zone_zharka_static] (статическая)
ZS_BFUZZ [zone_burning_fuzz] (статическая)

Добавлено (31.07.2011, 12:00:56)
---------------------------------------------
[spoiler]

Новые монстры
Введение
Многие часто сталкиваются с тем, что при попытке добавления монстров не попавшими в финальную версию игра может вылетать. Попробую рассказать, как это дело можно исправить.
Для примера возьму кошек (уж очень они мне нравятся)
Добавить их можно отредактировать файл all.spawn, либо динамически создать в игре через функцию alife:create().
Вылет при появлении
Обычно сопровождается сообщением в логе:
Arguments : Can't open section 'cat_weak'
Это значит, что монстр у нас не до конца описан. В файле конфигурации идет секция
[m_cat_e]:monster_base
Но для создания разных по силе конфигураций монстров обычно используется такая штука. Создается секция вида
[cat_weak]:m_cat_e
то есть ссылка на основную конфигурацию, а потом указываются параметры, которые отличаются от нее. Например сила, здоровье, угол обзора и тд. Мы пока ограничимся просто добавлением этой секции. В файле config\creatures\m_cat.ltx в конце допишем [cat_weak]:m_cat_e. Запускаем, добавляем кошку, вылетаем с ошибкой:
Arguments : Can't find variable smart_terrain_choose_interval in [cat_weak]
Что ж, добавим и этот параметр. Посмотрим, какой он у собак, и сделаем также:
smart_terrain_choose_interval = 00:15:00
Запускаем, вылетаем с ошибкой:
Arguments : Can't find variable satiety_threshold in [cat_weak]
Вобщем, добавляем параметры, по кошка не станет нормально появлятся. Такие ошибки легко локализуются и исправляются.
Ну, на всякий случай, нужно добавить еще две строчки:
critical_wound_threshold = 0.4
critical_wound_decrease_quant = 0.
После этого кошка появляется, бегает, с 30 метров бежит нас кушать. Мы этого не хотим, стреляем в нее, и у нас происходит
Вылет при убийстве
Это знаменитая ошибка:
Arguments : LUA error: e:\stalker\gamedata\scripts\_g.script:20 ........
Самое просто и неправильное решение - закоментировать 20-ю строку скрипта _g.script, вылет исчезнет, но ошибка никуда не денется. Я не могу сказать с уверенностью, к чему игнорирование этого факта может привести, так как исправлял причину, а не следствие.
Путем нехитрых логических размышлений решение было найдено. Вернее тупым перебором всего, что относилось к делу, криками на форумах, битьем головой о стенку... Потом пришло озарение, вместе с сакраментальным вопросом "что происходит после смерти?" А происходит добавление в статистику убитого объекта (монстра, нпс-а). Поэтому лезем в скрипт xr_statistic.script. В самом начале видим объявление переменной
local killCountProps = {...}
в которой кошек нет. Поэтому добавляем их туда (например, в конец), для начисления очков опыта:
cat_weak = 1, cat_normal = 2, cat_strong = 3,
Хотя мы сделали только cat_weak, но на будущее добавим и остальных. Затем идет перечисление используемых классов монстров:
monster_classes = {
кошек нет и здесь, добавляем:
[clsid.cat_s] = "cat",
Смотрим дальше, видим функцию addKillCount(npc), которая определяет сообщество (community) убитого. Функция вызывает getNpcType(npc), которая находится в этом же скрипте. А там идет обращение к функции IsStalker(npc), и возвращает сообщество и ранг убиенного.
Но тут про мостров ни слова, а значит идем дальше. Функция IsStalker(npc) обнаруживается в скрипте _g.script. Просматривая его обнаруживаем следующие интересующие нас функции:
• is_object_monster(obj)
кошек нет, добавляем рядом с собаками:
otype == clsid.cat or
• IsMonster (object, class_id)
кошки есть, ничего не трогаем.
Для страховки проверим еще одни файл, class_registrator.script. Находим в нем строку
cs_register (object_factory, "CCat", "se_monster.se_monster", "SM_CAT_S", "cat_s")
и успокаиваемся на этом. Запускаем, убиваем, подходим, пытаемся обыскать - вылетаем. Потому что случился
Вылет при обыске
Ну тут уже проще. Вспоминаем, что у нас показывается в инвентаре убитого? Иконка растерзанного трупа. Проверяем m_cat.ltx - действительно, параметр icon отсутствует. Тут появляется два пути.
Первый - нарисовать новую иконку, вставить ее в файл ui_npc_monster.dds, определить координаты и добавить их в xml-описатель ui_npc_monster.xml. И так для каждого нового монстра.
Второй - использовать общую иконку для всех монстров, у которых отсутствует этот параметр. Мы им и воспользуемся, так как для тестовых целей сойдет, а для серьезного применения все равно необходимо иметь хоть какие-то художественные навыки (если кто видел мой тестовый мод "15 кошек", то помнят тот ужас вместо иконки кошки :) )
Для этого отредактируем файл defines.ltx , так как именно в нём содержится секция monster_base, общая для всех монстров. Открываем, ищем секцию, и вставляем
icon = ui_frame_error_sign_red
Это будет такой красный крест в круге. Запускаем, убиваем, обыскиваем и не вылетаем.
Итак, свежедобавленный монстр бегает, живет, нападает. Однако та же кошка по умолчанию невероятно сильна, убивает с одного удара, поэтому для нормальной жизни необходимо подредактировать секцию атаки.
Внимание!!!
Огромный минус в том, что убитое животное не попадает в статистику, хотя мы вроде все для этого сделали. С этим предлагаю разобраться самим. Подсказка: в энциклопедии кошек тоже нет ;)

Добавлено (31.07.2011, 12:05:56)
---------------------------------------------
так идем дальше
[spoiler]

Содержимое файлов gamedata.db*
gamedata.db0
-ai:
| -alife
| -common
-anims:
| -camera_effects
| -editor
| -helicopter
| -path
-config:
| -creatures
| -gameplay
| -misc
| -models:
| | -capture
| | -objects
| | -vehicles
| | -weapons
| -mp:
| | -soundmessages
| | -weapons_mp
| -prefetch
| -scripts:
| | -agr
| | -cit
| | -dar
| | -ds
| | -mil
| | -pri
| | -rad
| | -val
| | -yan
| -text:
| | -map_desc
| -ui
| -weapons
| -weathers
-levels:
| -l01_escape:
| | -meshes
| | -terrain
| -l02_garbage:
| | -meshes
| | -terrain
| -l03_agroprom:
| | -meshes
| | -terrain
| -l03u_agr_underground
| -l04_darkvalley:
| | -meshes
| | -terrain
| -l04u_labx18

gamedata.db1
-levels:
| -l04u_labx18:
| | -meshes
| -l05_bar:
| | -terrain
| -l06_rostok:
| | -meshes
| | -terrain
| -l07_military:
| | -meshes
| | -terrain
| -l08_yantar:
| | -meshes
| | -terrain
| -l08u_brainlab:
| | -meshes
| -l10_radar
gamedata.db2
-levels:
| -l10_radar:
| | -meshes
| | -terrain
| -l10u_bunker
| -l11_pripyat:
| | -meshes
| | -terrain
| -l12_stancia:
| | -meshes
| | -terrain
| -l12_stancia_2
gamedata.db3
-levels:
| -l12_stancia_2:
| | -meshes
| | -terrain
| -l12u_control_monolith
| -l12u_sarcofag
| -testers_mp_agroprom:
| | -terrain
| -testers_mp_atp:
| | -terrain
| -testers_mp_bath:
| | -terrain
| -testers_mp_darkvalley:
| | -meshes
| | -terrain
| -testers_mp_factory:
| | -terrain
| -testers_mp_lost_village:
| | -terrain
| -testers_mp_military_1:
| | -meshes
| | -terrain
| -testers_mp_military_2:
| | -terrain
| -testers_mp_pool
| -testers_mp_railroad:
| | -terrain
| -testers_mp_rostok

Добавлено (31.07.2011, 12:07:06)
---------------------------------------------
так дальше[spoiler]gamedata.db4
-levels:
| -testers_mp_rostok:
| | -meshes
| | -terrain
| -testers_mp_workshop:
| | -terrain
-meshes:
| -actors:
| | -bandit
| | -barman
| | -dolg
| | -ecolog
| | -hero
| | -izgoy
| | -killer
| | -militari
| | -monolit
| | -nauchniy
| | -neytral
| | -novice
| | -protect
| | -soldier
| | -stalker_mp
| | -stalker_zombi
| | -svoboda
| | -trader
| | -ucheniy
| -dm
| -equipments
| -food
| -monsters:
| | -burer
| | -cat
| | -chimera
| | -crow
| | -dark_stalker
| | -dog
| | -flesh
| | -izlom
| | -kontroler
| | -krovosos
| | -mutant_boar
| | -phantom
| | -poltergeist
| | -pseudodog
| | -psevdogigant
| | -rat
| | -snork
| | -stalker_zombi
| | -topolinypuh
| | -tushkano
| | -zombi
| -objects:
| | -dynamics:
| | | -balon
| | | -bed
| | | -box:
| | | | -prt
| | | -chair
| | | -decor
| | | -plitka
| -physics:
| | -anomaly
| | -balon
| | -box:
| | | -prt
| | -dead_body
| | -decor:
| | | -prt
| | -door:
| | | -prt
| | -equipment_cache
| | -keyboard
| | -krovati
| | -large_trash:
| | | -prt
| | -light:
| | | -new_light
| | -rope
| | -shkaf
| | -small_trash:
| | | -prt
| | -stol
| | -stul
| | -target
| | -technica
| | -test:
| | | -old
| | -vehicles:
| | | -btr
| | | -kamaz:
| | | | -old
| | | -mi24:
| | | | -part
| | | -moskvich
| | | -niva
| | | -tr13
| | | -uaz
| | | -zaz
| | -zabor:
| | | -prt
| -weapons:
| | -abakan
| | -ak-74u
| | -ak74
| | -ammo
| | -aptechka
| | -artefact
| | -bandage
| | -beretta92fs
| | -binoculars
| | -bm_16
| | -bolt
| | -bred
| | -colt1911
| | -desert_eagle
| | -fn2000
| | -fort
| | -g36
| | -gauss
| | -grenade
| | -groza
| | -hpsa
| | -knife
| | -kolbasa
| | -l85
| | -lr300
| | -mounted_weapons
| | -mp5
| | -p90
| | -pb
| | -pm
| | -rg-6
| | -rpg_7
| | -sig220
| | -sig550
| | -sigaret
| | -spas12
| | -svd
| | -svu
| | -toz34
| | -upgrade
| | -usp_45
| | -val
| | -vintorez
| | -vodka
| | -walter_99
| | -winchester1300

Добавлено (31.07.2011, 12:11:53)
---------------------------------------------
так продолжение предыдущего поста [spoiler]

-scripts
-shaders:
| -r1:
| | -shared
| -r2:
| | -shared
| | -test
| -shared
-sounds:
| -actor
| -affects
| -alexmx
| -ambient:
| | -arena
| | -bar
| | -indoors
| | -random
| | -rnd_outdoor
| | -underground
| | -x16
| | -x18
| -anomaly
| -car
| -characters_voice:
| | -human_01:
| | | -bandit:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -friendly_fire
| | | | | -friendly_grenade
| | | | | -friend_hitted
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | -music
| | | | -reactions:
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing
| | | | | -see_something
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -fatique
| | | | | -health
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -radiation
| | | | | -sleep
| | | | | -starvation
| | | | -talk:
| | | | | -abuse
| | | | | -accept
| | | | | -friendly_greeting
| | | | | -intros
| | | | | -jokes
| | | | | -leave
| | | | | -neutral_greeting
| | | | | -raid
| | | | | | -init
| | | | | | -reaction
| | | | | -rejection
| | | | | -stories
| | | | | -trade
| | | | | | -no
| | | | | | -yes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | | | -stop
| | | | -waiting:
| | | | | -moveout
| | | -dolg:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -enemy_down
| | | | | -enemy_hit
| | | | | -fire
| | | | | -friendly_fire
| | | | | -friend_hitted
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -threat
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | | -wounded_thanx
| | | | -music
| | | | -reactions:
| | | | | -box
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing
| | | | | -raid
| | | | | -see_something
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -fatique
| | | | | -health
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -radiation
| | | | | -sleep
| | | | | -starvation
| | | | -talk:
| | | | | -abuse
| | | | | -accept
| | | | | -friendly_greeting
| | | | | -intros
| | | | | -jokes
| | | | | -leave
| | | | | -neutral_greeting
| | | | | -raid:
| | | | | | -init
| | | | | | -reaction
| | | | | -rejection
| | | | | -stories
| | | | | -trade:
| | | | | | -no
| | | | | | -yes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | | | -stop
| | | | -waiting:
| | | | | -moveout
| | | -ecolog:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -enemy_down
| | | | | -enemy_hit
| | | | | -fire
| | | | | -friendly_fire
| | | | | -friend_hitted
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -threat
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy:
| | | | | | -aptechku
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | | -wounded_thanx

Добавлено (31.07.2011, 12:16:21)
---------------------------------------------
продолжение[spoiler]

| | | | -reactions:
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing
| | | | | -see_something
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -fatique
| | | | | -health
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -radiation
| | | | | -sleep
| | | | | -starvation
| | | | -talk:
| | | | | -abuse
| | | | | -accept
| | | | | -friendly_greeting
| | | | | -intros
| | | | | -jokes
| | | | | -leave
| | | | | -neutral_greeting
| | | | | -raid:
| | | | | | -init
| | | | | | -reaction
| | | | | -rejection
| | | | | -stories
| | | | | -trade:
| | | | | | -no
| | | | | | -yes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | | | -stop
| | | | -waiting:
| | | | | -moveout
| | | -freedom:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -enemy_down
| | | | | -enemy_hit
| | | | | -fire
| | | | | -friendly_fire
| | | | | -friend_hitted
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -threat
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | | -wounded_thanx
| | | | -music
| | | | -reactions:
| | | | | -box
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing
| | | | | -see_something
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -fatique
| | | | | -health
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -radiation
| | | | | -sleep
| | | | | -starvation
| | | | -talk:
| | | | | -abuse
| | | | | -accept
| | | | | -friendly_greeting
| | | | | -intros
| | | | | -jokes
| | | | | -leave
| | | | | -neutral_greeting
| | | | | -raid:
| | | | | | -init
| | | | | | -reaction
| | | | | -rejection
| | | | | -stories
| | | | | -trade:
| | | | | | -no
| | | | | | -yes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | | | -stop
| | | | -waiting:
| | | | | -moveout
| | | -killer:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -friendly_fire
| | | | | -friendly_grenade
| | | | | -friend_hitted
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy:
| | | | | | -aptechku
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | | -wounded_thanx
| | | | -reactions:
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing
| | | | | -see_something
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -fatique
| | | | | -health
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -radiation
| | | | | -sleep
| | | | | -starvation
| | | | -talk:
| | | | | -abuse
| | | | | -accept
| | | | | -friendly_greeting
| | | | | -intros
| | | | | -jokes
| | | | | -leave
| | | | | -neutral_greeting
| | | | | -raid:
| | | | | | -init
| | | | | | -reaction
| | | | | -rejection
| | | | | -stories
| | | | | -trade:
| | | | | | -no
| | | | | | -yes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | | | -stop
| | | | -waiting:
| | | | | -moveout
| | | -military:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -enemy_down
| | | | | -enemy_hit
| | | | | -fire
| | | | | -friend_hitted
| | | | | -friendly_fire
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -threat
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy:
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | -reactions:
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing

Добавлено (31.07.2011, 12:17:09)
---------------------------------------------
дальше[spoiler]

| | | | | -see_something
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -fatique
| | | | | -health
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -radiation
| | | | | -sleep
| | | | | -starvation
| | | | -talk:
| | | | | -abuse
| | | | | -accept
| | | | | -friendly_greeting
| | | | | -intros
| | | | | -jokes
| | | | | -leave
| | | | | -neutral_greeting
| | | | | -raid:
| | | | | | -init
| | | | | | -reaction
| | | | | -rejection
| | | | | -stories
| | | | | -trade:
| | | | | | -no
| | | | | | -yes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | | | -stop
| | | | -waiting:
| | | | | -moveout
| | | -monolith:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -enemy_down
| | | | | -enemy_hit
| | | | | -fire
| | | | | -friend_hitted
| | | | | -friendly_fire
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -threat
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy:
| | | | | | -aptechku
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | | -wounded_thanx
| | | | -reactions:
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing
| | | | | -see_something
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -fatique
| | | | | -health
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -radiation
| | | | | -sleep
| | | | | -starvation
| | | | -talk:
| | | | | -abuse
| | | | | -accept
| | | | | -friendly_greeting
| | | | | -intros
| | | | | -jokes
| | | | | -leave
| | | | | -neutral_greeting
| | | | | -raid:
| | | | | | -init
| | | | | | -reaction
| | | | | -rejection
| | | | | -stories
| | | | | -trade:
| | | | | | -no
| | | | | | -yes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | | | -stop
| | | | -waiting:
| | | | | -moveout
| | | -newbie
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -enemy_down
| | | | | -enemy_hit
| | | | | -fire
| | | | | -friend_hitted
| | | | | -friendly_fire
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -threat
| | | | | -tolls
| | | | -help:
| | | | | -wounded
| | | | | -wounded_heavy
| | | | | -wounded_thanx
| | | | -music
| | | | -reactions:
| | | | | -box
| | | | | -joke
| | | | | -music
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -sleep
| | | | -talk:
| | | | | -intros
| | | | | -jokes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | -stalker
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -enemy_down
| | | | | -enemy_hit
| | | | | -fire
| | | | | -friend_hitted
| | | | | -friendly_fire
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -threat
| | | | | -tolls
| | | | -help:
| | | | | -wounded
| | | | | -wounded_heavy
| | | | | -wounded_thanx
| | | | -music
| | | | -reactions:
| | | | | -box
| | | | | -joke
| | | | | -music
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -sleep
| | | | -talk:
| | | | | -intros
| | | | | -jokes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | -zombied
| | | | -fight:
| | | | | -attack
| | | | | -death
| | | | | -enemy
| | | | | -hit
| | | | -states:
| | | | | -idle
| | | | | -rising
| | -human_02:
| | | -bandit:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -friendly_fire
| | | | | -friendly_grenade
| | | | | -friend_hitted
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | -music
| | | | -reactions:
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing
| | | | | -see_something
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -fatique
| | | | | -health
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -radiation
| | | | | -sleep
| | | | | -starvation
| | | | -talk:
| | | | | -abuse
| | | | | -accept
| | | | | -friendly_greeting
| | | | | -intros
| | | | | -jokes
| | | | | -leave
| | | | | -neutral_greeting
| | | | | -raid
| | | | | | -init
| | | | | | -reaction
| | | | | -rejection
| | | | | -stories
| | | | | -trade
| | | | | | -no
| | | | | | -yes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | | | -stop
| | | | -waiting:
| | | | | -moveout
| | | -dolg:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -enemy_down
| | | | | -enemy_hit
| | | | | -fire
| | | | | -friendly_fire
| | | | | -friend_hitted
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -threat
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | | -wounded_thanx
| | | | -music
| | | | -reactions:
| | | | | -box
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing
| | | | | -raid
| | | | | -see_something
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -fatique
| | | | | -health
| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -radiation
| | | | | -sleep
| | | | | -starvation
| | | | -talk:
| | | | | -abuse
| | | | | -accept
| | | | | -friendly_greeting
| | | | | -intros
| | | | | -jokes
| | | | | -leave
| | | | | -neutral_greeting
| | | | | -raid:
| | | | | | -init
| | | | | | -reaction
| | | | | -rejection
| | | | | -stories
| | | | | -trade:
| | | | | | -no
| | | | | | -yes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | | | -stop
| | | | -waiting:
| | | | | -moveout
| | | -ecolog:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -enemy_down
| | | | | -enemy_hit
| | | | | -fire
| | | | | -friendly_fire
| | | | | -friend_hitted
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -threat
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy:
| | | | | | -aptechku
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | | -wounded_thanx
| | | | -reactions:
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing
| | | | | -see_something
| | | | | -story
| | | | -states:
| | | | | -breath
| | | | | -fatique
| | | | | -health

Добавлено (31.07.2011, 12:17:48)
---------------------------------------------
дальше[spoiler]

| | | | | -idle
| | | | | -panic_human
| | | | | -panic_monster
| | | | | -radiation
| | | | | -sleep
| | | | | -starvation
| | | | -talk:
| | | | | -abuse
| | | | | -accept
| | | | | -friendly_greeting
| | | | | -intros
| | | | | -jokes
| | | | | -leave
| | | | | -neutral_greeting
| | | | | -raid:
| | | | | | -init
| | | | | | -reaction
| | | | | -rejection
| | | | | -stories
| | | | | -trade:
| | | | | | -no
| | | | | | -yes
| | | | | -use
| | | | -threat:
| | | | | -back_off
| | | | | -drop_weapon
| | | | | -stop
| | | | -waiting:
| | | | | -moveout
| | | -freedom:
| | | | -fight:
| | | | | -attack
| | | | | -backup
| | | | | -cover_fire
| | | | | -death
| | | | | -detour
| | | | | -enemy
| | | | | -enemy_down
| | | | | -enemy_hit
| | | | | -fire
| | | | | -friendly_fire
| | | | | -friend_hitted
| | | | | -grenade
| | | | | -hit
| | | | | -searching_enemy
| | | | | -threat
| | | | | -tolls
| | | | -hail
| | | | -help:
| | | | | -not_wounded
| | | | | -wounded
| | | | | -wounded_heavy
| | | | | -wounded_not_see_helper
| | | | | -wounded_psy
| | | | | -wounded_see_helper
| | | | | -wounded_thanx
| | | | -music
| | | | -reactions:
| | | | | -box
| | | | | -dead_enemy
| | | | | -dead_friend
| | | | | -dead_mutant
| | | | | -dead_neutral
| | | | | -hear_something
| | | | | -joke
| | | | | -music
| | | | | -nothing




Все кому я нужен могут найти меня по этому адресу : #EGGO_TM в общем буду рад пообщаться )
# 42
Четверг, 04.08.2011, 19:39:45

Ранг: Разведчик
Сообщений: 367
Награды: 64
Репутация: 2435 Регистрация: 22.07.2011  

добавляем проводника



Все кому я нужен могут найти меня по этому адресу : #EGGO_TM в общем буду рад пообщаться )
# 43
Вторник, 16.08.2011, 04:18:06

Ранг: Разведчик
Сообщений: 367
Награды: 64
Репутация: 2435 Регистрация: 22.07.2011  

[spoiler]Как изменить параметры конкретного оружия?
Параметры стволов заданы в конфигурационных файлах по адресу gamedata\configs\weapons
Возьмем, для примера, конфиг w_g36.ltx. Он делится на разделы:
Первый раздел
Здесь хранится общая информация о оружии - его класс, тип, ссылки на спавн и т.д. Нас интересуют следующие строки:
description = enc_weapons1_wpn-g36 - ссылка на string_id, из которого игра подгружает описание этого оружия.
ef_main_weapon_type = 2 - основной тип, к которому принадлежит оружие
ef_weapon_type = 6 - подтип, к которому принадлежит оружие
Второй раздел
Содержит модификаторы, которые даются к углу зрения/дальности обзора NPC, держащего это оружие в руках:
holder_range_modifier = 1.85 - во сколько раз увеличивается eye_range
holder_fov_modifier = 0.3 - во сколько раз увеличивается eye_fov
Третий раздел
Содержит данные о самом оружии, его некоторых характеристиках:
cost = 18000 - базовая цена (торговцы умножают её на некоторый коэффициент)
weapon_class = assault_rifle - класс оружия (здесь - штурмовая винтовка)
ammo_mag_size = 30 - размер магазина
ammo_class = ammo_5.56x45_ss190, ammo_5.56x45_ap - типы используемых патронов
grenade_class = ammo_m209 - тип используемых гранат
fire_modes = 1, -1 - режимы ведения огня
hand_dependence = 1 - засивимость о рук (?) - возможно, речь идет о качании ствола
single_handed = 0 - держится ли только в одной руке
slot = 2 - слот в инвентаре
animation_slot = 2 - вид анимации (для пистолета/для винтовки)
inv_name = wpn-g36 - ссылка на имя, отображаемое в инвентаре, тоже берется из string table, как и описание
inv_name_short = wpn-g36 - короткое имя; в данном случае используется то же самое
inv_weight = 3.6 - вес
inv_grid_width = 5 - координаты первого угла иконки по x
inv_grid_height = 2 - координаты первого угла иконки по y
inv_grid_x = 0 - координаты второго угла иконки по x
inv_grid_y = 10 - координаты второго угла иконки по y
Четвертый раздел
В четвертом разделе хранится информация о износе/отдаче оружия. Практически все параметры там снабжены комментариями, поэтому приведу лишь самые интересные:
cam_relax_speed = 5.7 - скорость возврата в исходное положение
cam_dispersion = 0.2 - увеличения угла (в градусах) с каждым выстрелом
fire_dispersion_condition_factor = 5 - увеличение дисперсии в процентах при максимальном износе
misfire_probability = 0.003 - вероятность осечки при максимальном износе
misfire_condition_k = 0.05 - порог (в данном случае - 5%), после которого оружие может заклинивать
condition_shot_dec = 0.0002 - увеличение износа при каждом выстреле
Пятый раздел
Здесь хранится множество параметров, из которых наиболее интересны эти:
PDM_disp_base = 3.0 - множитель, на который умножается базовая дисперсия оружия, когда ГГ (Главный Герой) стоит на месте в полный рост;
PDM_disp_vel_factor = 1.3 - множитель, на который умножается базовая дисперсия оружия, когда ГГ крутит оружием или бежит;
PDM_disp_accel_factor = 1.3 - множитель, на который умножается базовая дисперсия оружия, когда ГГ бежит в спринте;
PDM_crouch = 1.0 - множитель, на который умножается базовая дисперсия оружия, когда ГГ идет пригнувшись;
PDM_crouch_no_acc = 1.0 - множитель, на который умножается базовая дисперсия оружия, когда ГГ стоит на месте, пригнувшись;
hit_power = 0.50, 0.54, 0.57, 0.60 - сила выстрела
hit_impulse = 105 - импульс пули (сила, которую летящая пуля передает жертве, влияет на поведение ragdoll-тела)
hit_type = fire_wound - тип причиняемых повреждений, в данном случае - пулевые ранения (параметр в синглплеере ни на что не влияет)
fire_distance = 600 - максимальная дистанция для выстрела
bullet_speed = 925 - начальная скорость пули
hud = wpn_g36_hud - внешний вид оружия
Шестой раздел
position = -0.026, -0.132, 0.0 - позиция по отношению к игроку (?)
orientation = 0, 0, 0 - направление, в которое смотрит ствол (?)
Седьмой раздел
Содержит описания визуальной стороны оружия и некоторые другие параметры:
startup_ammo = 90 - как нетрудно догадаться, стартовое количество патронов (в синглплеере ни на что не влияет)
visual = weapons\g36\wpn_g36.ogf - модель оружия, используемая NPC, а также игроком при виде от третьего лица
ph_mass = 4 - физическая масса, используемая при расчетах
scope_status = 1 - ситуация со съемным прицелом
silencer_status = 0 - ситуация со съемным глушителем
grenade_launcher_status = 0 - ситуация с подствольным гранатометом
Параметры:
0 - нет, новый прикрепить нельзя
1 - уже есть, несъемный
2 - нет, но можно установить новый
zoom_enabled = true - есть ли зум (прицеливание)
scope_zoom_factor = 33.3 - какой зум дает прицеливание (здесь - 1.8х)
scope_texture = wpn\wpn_crosshair_g36 - текстура прицельной сетки
shell_point = 0.15, 0.0, -0.05 - точка вылета гильз
shell_dir = 0.0, 1.0, 0.0
fire_point = -0.000000,0.062000,0.134000 - точка выстрела
fire_point2 = 0.30, 0.00, 0.05 - точка выстрела (2)
fire_bone = wpn_body
orientation = 0, 0, 0 - направление
position = 0, 0, 0 - позиция
visual = weapons\g36\wpn_g36_hud.ogf - модель, отображаемая у нас в руках
Изменение описаний
Описания оружия хранятся в файле: ...\S.T.A.L.K.E.R\gamedata\config\text\rus\string_table_enc_weapons.xml
В нем хранятся строки с названиями и описаниями, на которые ссылаются конфиги оружия. Например, тот же G36 ссылается сюда:
[...]
<string id="enc_weapons1_wpn-g36">
<text>Штурмовая винтовка немецкого производства, представляющая собой первоклассный образец
современного оружия - лёгкого, надёжного и эргономичного.\n Боеприпасы:\n обычный 5,56x45 мм
SS109,\n бронебойный 5,56x45 мм АР.</text>
[...]
<string id="wpn-g36">
<text>ГП37</text>
[...]Меняя их содержимое, мы меняем описания/названия данного оружия.

Добавлено (15.08.2011, 21:31:42)
---------------------------------------------
[Новые монстры]
Введение
Многие часто сталкиваются с тем, что при попытке добавления монстров не попавшими в финальную версию игра может вылетать. Попробую рассказать, как это дело можно исправить.
Для примера возьму кошек (уж очень они мне нравятся)
Добавить их можно отредактировать файл all.spawn, либо динамически создать в игре через функцию alife:create().
Вылет при появлении
Обычно сопровождается сообщением в логе:
Arguments : Can't open section 'cat_weak'
Это значит, что монстр у нас не до конца описан. В файле конфигурации идет секция
[m_cat_e]:monster_base
Но для создания разных по силе конфигураций монстров обычно используется такая штука. Создается секция вида
[cat_weak]:m_cat_e
то есть ссылка на основную конфигурацию, а потом указываются параметры, которые отличаются от нее. Например сила, здоровье, угол обзора и тд. Мы пока ограничимся просто добавлением этой секции. В файле config\creatures\m_cat.ltx в конце допишем [cat_weak]:m_cat_e. Запускаем, добавляем кошку, вылетаем с ошибкой:
Arguments : Can't find variable smart_terrain_choose_interval in [cat_weak]
Что ж, добавим и этот параметр. Посмотрим, какой он у собак, и сделаем также:
smart_terrain_choose_interval = 00:15:00
Запускаем, вылетаем с ошибкой:
Arguments : Can't find variable satiety_threshold in [cat_weak]
Вобщем, добавляем параметры, по кошка не станет нормально появлятся. Такие ошибки легко локализуются и исправляются.
Ну, на всякий случай, нужно добавить еще две строчки:
critical_wound_threshold = 0.4
critical_wound_decrease_quant = 0.
После этого кошка появляется, бегает, с 30 метров бежит нас кушать. Мы этого не хотим, стреляем в нее, и у нас происходит
Вылет при убийстве
Это знаменитая ошибка:
Arguments : LUA error: e:\stalker\gamedata\scripts\_g.script:20 ........
Самое просто и неправильное решение - закоментировать 20-ю строку скрипта _g.script, вылет исчезнет, но ошибка никуда не денется. Я не могу сказать с уверенностью, к чему игнорирование этого факта может привести, так как исправлял причину, а не следствие.
Путем нехитрых логических размышлений решение было найдено. Вернее тупым перебором всего, что относилось к делу, криками на форумах, битьем головой о стенку... Потом пришло озарение, вместе с сакраментальным вопросом "что происходит после смерти?" А происходит добавление в статистику убитого объекта (монстра, нпс-а). Поэтому лезем в скрипт xr_statistic.script. В самом начале видим объявление переменной
local killCountProps = {...}
в которой кошек нет. Поэтому добавляем их туда (например, в конец), для начисления очков опыта:
cat_weak = 1, cat_normal = 2, cat_strong = 3,
Хотя мы сделали только cat_weak, но на будущее добавим и остальных. Затем идет перечисление используемых классов монстров:
monster_classes = {
кошек нет и здесь, добавляем:
[clsid.cat_s] = "cat",
Смотрим дальше, видим функцию addKillCount(npc), которая определяет сообщество (community) убитого. Функция вызывает getNpcType(npc), которая находится в этом же скрипте. А там идет обращение к функции IsStalker(npc), и возвращает сообщество и ранг убиенного.
Но тут про мостров ни слова, а значит идем дальше. Функция IsStalker(npc) обнаруживается в скрипте _g.script. Просматривая его обнаруживаем следующие интересующие нас функции:
• is_object_monster(obj)
кошек нет, добавляем рядом с собаками:
otype == clsid.cat or
• IsMonster (object, class_id)
кошки есть, ничего не трогаем.
Для страховки проверим еще одни файл, class_registrator.script. Находим в нем строку
cs_register (object_factory, "CCat", "se_monster.se_monster", "SM_CAT_S", "cat_s")
и успокаиваемся на этом. Запускаем, убиваем, подходим, пытаемся обыскать - вылетаем. Потому что случился
Вылет при обыске
Ну тут уже проще. Вспоминаем, что у нас показывается в инвентаре убитого? Иконка растерзанного трупа. Проверяем m_cat.ltx - действительно, параметр icon отсутствует. Тут появляется два пути.
Первый - нарисовать новую иконку, вставить ее в файл ui_npc_monster.dds, определить координаты и добавить их в xml-описатель ui_npc_monster.xml. И так для каждого нового монстра.
Второй - использовать общую иконку для всех монстров, у которых отсутствует этот параметр. Мы им и воспользуемся, так как для тестовых целей сойдет, а для серьезного применения все равно необходимо иметь хоть какие-то художественные навыки (если кто видел мой тестовый мод "15 кошек", то помнят тот ужас вместо иконки кошки :) )
Для этого отредактируем файл defines.ltx , так как именно в нём содержится секция monster_base, общая для всех монстров. Открываем, ищем секцию, и вставляем
icon = ui_frame_error_sign_red
Это будет такой красный крест в круге. Запускаем, убиваем, обыскиваем и не вылетаем.
Итак, свежедобавленный монстр бегает, живет, нападает. Однако та же кошка по умолчанию невероятно сильна, убивает с одного удара, поэтому для нормальной жизни необходимо подредактировать секцию атаки.
Внимание!!!
Огромный минус в том, что убитое животное не попадает в статистику, хотя мы вроде все для этого сделали. С этим предлагаю разобраться самим. Подсказка: в энциклопедии кошек тоже нет ;)

Добавлено (15.08.2011, 21:38:15)
---------------------------------------------
[spoiler]

Создание "перемещающихся" аномалий
Небольшое вступление
"Перемещающиеся" аномалии с самого момента релиза очень заинтересовали коммьюнити. Выдвигалось множество предположений о принципе их работы. На самом деле, всё сделано достаточно незамысловато. В свойствах аномалий прописываются параметры, в которых указывается в какой промежуток времени они будут активны. Таким образом создаются целые цепочки из аномалий, параметры которых взаимосвязаны. В оригинале всего две таких цепочки: в туннеле на Кордоне и в подземелье Агропрома.
Описание параметров
Всего используются три параметра:
enabled_time - через какое время после начала отсчёта аномалия включится.
disabled_time - через какое время после начала отсчёта аномалия отключится.
start_time_shift - на сколько сдвинется момент начала отсчёта времени. (Использовать необязательно)
После отключения аномалии процесс повторяется. Следующее включение произойдёт через промежуток времени прописанный в disable_time.
В Level Editor'е эти параметры находятся в свойствах аномалии. При использовании ACDC параметры прописываются "в теле" нужной аномалии. Значения указываются в секундах.
Небольшая наглядность
Создадим "перемещающуюся" аномалию, которая будет менять своё местоположение каждые четыре секунды. Для этого создадим несколько аномалий (для примера взято 3 штуки).
Для первой аномалии пропишем:
enabled_time = 4
disabled_time = 8
start_time_shift = 8
Для второй:
enabled_time = 4
disabled_time = 8
start_time_shift = 4
Для третьей:
enabled_time = 4
disabled_time = 8
Таким образом, первой будет активироваться третья аномалия, работать четыре секунды и деактивироваться. Сразу после неё будет активироваться вторая аномалия, работать 4 секунды, ну и так далее... Вот так и создаётся ощущение того, что аномалия перемещается. Конечно, это только один из примеров использования этих параметров. Обладая должным желанием и терпением, можно делать целые аномальные поля, где каждая аномалия будет вести себя независимо от других, но вместе они будут образовывать смертельно опасное место.

Добавлено (15.08.2011, 22:01:23)
---------------------------------------------
[spoiler]

Inventory new.xml
Оформление инвентаря:
По пути gamedata.db0/config/ui/ лежит файл inventory_new.xml содержащий координаты объектов инвентаря.
Инвентарные слоты состоят из багграундных текстур, и слотовых сеток.
К примеру строки
<belt_slots x="0" y="80" width="1024" height="172">
<texture>ui_slots_belt</texture>
</belt_slots>
содержат координаты (x="0" y="80") и размер (width="1024" height="172") багграундной текстурки ui_slots_belt для двух оружейных слотов и слота ремня.

А строки
<dragdrop_belt x="645" y="136" width="410" height="60"
cell_width = "60" cell_height="60" rows_num="1" cols_num="5"/>
содержат координаты (x="645" y="136"), размер сетки(width="410" height="60"), размер одной ячейки сетки (cell_width = "60" cell_height="60"), число строк (rows_num="1") и столбцов (cols_num="5") слотовой сетки инвентаря.
Отсчет координат x y идет с левого верхнего угла.
Меняя значения приведенных значения можно изменять внешний вид инвентаря.
________________________________________
Примеры:
Изменив значения в строках
<dragdrop_belt x="645" y="136" width="410" height="60"
cell_width = "60" cell_height="60" rows_num="1" cols_num="5"/>
на
<dragdrop_belt x="590" y="118" width="410" height="104"
cell_width = "52" cell_height="52" rows_num="2" cols_num="5"/>

у нас в ременном отделении под артефакты вместо 5ти, будет 10ть слотовых ячеек.
Или изменив координаты (x="870" y="725") в строках
<exit_button x="870" y="725" width="157" height="48">
....
....
</exit_button>
на координаты (x="10" y="10"), можно перенести кнопку Выхода(из инвентаря) из правого нижнего угла в левый верхний угол.

Добавлено (16.08.2011, 04:12:23)
---------------------------------------------
[spoiler тык]Сначала создадим тестовый скрипт например kfs.script,
дальше открываем его блокнотом или другим текстовым редактором
пишем:
function main()-стока отвечающая за включение скрипта.
spawn_npc() строка отвечающая за включения функции.
Ну и сама функция:
local spawn_point1 = vector():set(-226.2, -20.3, -158.4)
local obj = alife():create("esc_bandit_respawn_1",spawn_point1,28485, 48)
Позиция где будет стоять npc, а именно на кордоне чтобы узнать
позицию нужно воспользоваться программой S.T.A.L.K.E.R. Position Informer (можно скачать у нас в файлах).
local spawn_point1 = vector():set(-226.2, -20.3, -158.4)
Что мы именно будем спавнить в данном случае заспавним бандита
имена npc можно узнать в spawn_sections.ltx
local obj = alife():create("esc_bandit_respawn_1",spawn_point1,20579,80)
Геймес вертекс отвечает за то где будет распологаться npc в нашем случае
на кордоне, можно так же узнать через S.T.A.L.K.E.R. Position Informer
local obj = alife():create("esc_bandit_respawn_1",spawn_point1,28485, 48)
Вот как должно получиться:
function main()
spawn_npc()
end
function spawn_npc()
-- тест на кордоне в лагере навичков
local spawn_point1 = vector():set(-226.2, -20.3, -158.4)
local obj = alife():create("esc_bandit_respawn_1",spawn_point1,28485, 48)
end
Теперь необходимо включить наш скрипт заходим в bind_stalker.script
где расположено: death_manager.init_drop_settings()
Под ней вводим нашу функцию kfs.main() где kfs это имя скрипта который мы назвали, так всё теперь запускаем игру и смотрим.
Что бы расположить сразу несколько npc или монстров
просто под сторчкой делaйте несколькo копий вот так:
local obj = alife():create("esc_bandit_respawn_1",spawn_point1,28485, 48)
local obj = alife():create("esc_bandit_respawn_1",spawn_point1,28485, 48)
local obj = alife():create("esc_bandit_respawn_1",spawn_point1,28485, 48)
local obj = alife():create("esc_bandit_respawn_2",spawn_point1,28485, 48)
local obj = alife():create("esc_bandit_respawn_2",spawn_point1,28485, 48)

СКРИПТ ДЛЯ СПАВНА ЛЮБЫХ НАБОРОВ ОБЪЕКТОВ

Приведенный ниже скрипт является общей функцией, куда передаются данные.
Его можно положить в любой скриптовый файл.
Если же хотите, что бы функцию можно было вызывать также и из логики - то скрипт нужно положить в файл xr_effects.script.

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

Для каждого объекта надо указать кол-во: если нужен один объект то 1, если сто - то 100 и т.д.

Общая функция
Код:
function SpawnToNpcOrToLocation(tab_items,tab_where)
local count = 0
local pos, lvid, gvid, id, obj

local function Compare(id)
obj = alife():object(id)
return obj and obj.profile_name and obj:profile_name() == tab_where
end

for k, v in pairs(tab_items) do
if type(tab_where)=='table' then
for k, v in pairs (tab_items[k]) do
count = k
for i=1, count do
alife():create(v,vector():set(tab_where['x'],
tab_where['y'],tab_where['z']),
tab_where['lv'],tab_where['gv'])
end
end

elseif type(tab_where)=='string' then
if tab_where =="actor" then
obj = alife():actor()
else
for i=1, 65534 do
local predicate = Compare(i)
if predicate then
break
end
end
end

if obj == nil then return end
for k, v in pairs (tab_items[k]) do
count = k
for i=1, count do
alife():create(v, obj.position, obj.m_level_vertex_id, obj.m_game_vertex_id, obj.id)
end
end

elseif type(tab_where)=='number' then
obj = level_object_by_sid(tab_where)
if obj ~= nil then
id, pos, lvid, gvid= obj:id(), obj:position(), obj:level_vertex_id(), obj:game_vertex_id()
elseif obj == nil then
obj = alife():story_object(tab_where)
id, pos, lvid, gvid = obj.id, obj.position, obj.m_level_vertex_id, obj.m_game_vertex_id
for k, v in pairs (tab_items[k]) do
count = k
for i=1, count do
alife():create(v, pos, lvid, gvid, id)
end
end
end
end
end
end

Функции с передачей данных:

--для спавна по координатам:

function uny_spawn_1()
local tab_items ={
{[1]="exo_outfit"},
{[1]="af_cristall_flower"},
{[1]="wpn_fn2000"},
{[5]="ammo_5.56x45_ss190"},
{[3]="bread"},
{[5]="medkit_army"}}
local tab_where ={x=-22,y=-33,z=-66,lv=33333,gv=44}
this.SpawnToNpcOrToLocation(tab_items,tab_where)
end

--для спавна в инвентарь эктора:

function uny_spawn_2()
local tab_items ={
{[1]="exo_outfit"},
{[1]="af_cristall_flower"},
{[1]="wpn_fn2000"},
{[5]="ammo_5.56x45_ss190"},
{[3]="bread"},
{[5]="medkit_army"}}
local tab_where = "actor"
this.SpawnToNpcOrToLocation(tab_items,tab_where)
end

--для спавна в инвентарь NPC по его sid'у:

function uny_spawn_3()
local tab_items ={
{[1]="exo_outfit"},
{[2]="af_cristall_flower"},
{[1]="wpn_fn2000"},
{[5]="ammo_5.56x45_ss190"},
{[3]="bread"},
{[5]="medkit_army"}}
local tab_where = 006 -- это sid волка
this.SpawnToNpcOrToLocation(tab_items,tab_where)
end

Доработанный вариант дает возможностью спавнить по сиду как клиентским так и серверным, то есть находящимся в оффлайне объектам,
а также есть возможность спавнить NPC по их профильному имени, которое указывается в теге
<specific_character id =
в файлах character_desc_локация
и в файле npc_profile в теге <character id =

-- для спавна в инвентарь NPC по его профильному имени

function uny_spawn_4()
local tab_items ={
{[1]="ammo_12x70_buck"},
{[1]="ammo_12x76_dart"},
{[1]="ammo_12x76_zhekan"},
{[1]="wpn_toz34"},
{[1]="wpn_ak74u"},
{[1]="stalker_outfit"},
{[1]="mutant_zombie_hand"},
{[1]="mutant_snork_leg"}
}
local tab_where = "mil_Svoboda_trader" -- имя из профиля
this.SpawnToNpcOrToLocation(tab_items,tab_where)
end

Добавлено (16.08.2011, 04:13:39)
---------------------------------------------
[spoiler]ПОСТЭФФЕКТЫ И АНИМАЦИИ КАМЕРЫ

Часть первая.

Что в имени тебе моем?

Делать полный разбор всего содержимого папки anims я разумеется не буду.
Рассмотрим некоторые аспекты.
В этой папке находятся файлы содержащие набор ключей для запуска того или иного эффекта.
В корневой папке в основном находятся файлы постпроцессинга – с расширением ppe.
В подпапке camera_effects - эффекты камеры или анимации.
Какая между ними разница? Так как я не спец по 3D графике, то скажу просто - постэффект (или правильнее потспроцессинг) это такой шейдерный фильтр, который накладывается на текстуры игры, создавая цветовое изменение картинки.
Простой пример – постэффект teleport.ppe. При срабатывании телепорта, что мы видим? Правильно – белый свет, который делает экран полностью белым на несколько секунд. Или nightvision.ppe – активируется при включении прибора ночного видения. В игре их несколько. Эффект думаю вам знаком.

Собственно файлы постпроцессинга существует в игре в текстовом и компилированом виде.
В текстовом - в файлах по пути gamedata\config\scripts - например .earthshake.ltx или teleport.ltx
В них в числовом коде задан набор правил, как должен изменяться тот или иной параметр изображения эффекта во времени. Всего этих параметров - 16. Полный их разбор вы можете прочитать в статье "Формат файлов постпроцессинга" на stalkerin.gameru.net.
В том же .earthshake.ltx. - задано всего два параметра duality_h. и duality_v. - раздвоение изображения по горизонтали и по вертикали.
Тем самым мы имеем возможность вручную изменить эти параметры и сделать тот или эффект другим. Но здесь мы этого разбирать не будем, так как займемся не текстовыми, а компилированными файлами постпроцессинга из папки anims.

Что они дают

dead_zone.ppe - картинка приобретает белесый цвет.

radar_psi.ppe - дает небольшое раздвоение картинки+черный экран

psy_antenna.ppe – картинка окружающего мира становится бело-желтой как на радаре в конце локации – в зоне действия антенны.

yantar_underground_psi.ppe - эффект сильного раздвоение картинки

blink.ppe - вспышка белого света на секунду-другую

deadcity_wake.ppe - интересный эффект в игре не задействованный – сначала черный экран, раздвоение картинки, красный экран.

vibros.ppe - с этим все понятно – эффект выброса – красное небо, вспышки и т.д.

vibros_p.ppe - еще один выброс, не такой яркий. что-то вроде предвариловки выброса: эффект легкого землетрясения, плавающая резкость, плавающая яркость, звук радиационного фона, плюс ГГ роняет на землю в самом начале. Длительность секунд 20.

radiation.ppe - создает картинку радиационной зоны

fire_hit.ppe - постэффект на попадание в ГГ: заливка экрана красным

Анимации камеры
Что из себя представляют анимации камеры – думаю, понятно всем.
Вот краткий обзор того, что я успел опробовать.

drunk.anm - анимация алкогольного опьянения. В сочетании с постэффектом alcohol.ppe
дает весь набор состояний чувака с бодуна: предметы двоятся, резкость восприятия мира весьма снижена, в глазах белая пелена, качает из стороны в сторону. Одним словом – наглядный пример – пить вредно.

fatigue.anm - анимация усталости, ГГ медленно и слегка пошатывает в разные стороны.

head_shot.anm - анимка попадания пули в голову, ГГ дернет в разные стороны

fusker.anm- что то типа эффекта от удара: ГГ также не хило дернет по сторонам.

punch_effector.anm - по моему то же самое.

prison_1.anm - эффект удара по ГГ с сильным наклоном тела вниз.

dream.anm - любопытная анимка: дает эффект резкого падения ГГ на землю, взгляд камеры будет снизу вверх, потом ГГ поднимается.

shell_shock.anm - эффект легкой встряски камеры

hit_front.anm - что-то типа анимки попадания пули в тело спереди: ГГ слегка шатнет стороны.
Также там есть hit_back.anm, hit_front_left.anm, hit_front_right.anm, hit_left.anm – и т.д. Не проверял, но эффект по-моему предсказуемый.

earthquake.anm - дрожь земли, то бишь землетрясение. Обычно идет в паре с выбросом.

dis_consciousness.anm - еще одна прикольная анимка: вращение камеры как будто бы ГГ катится по земле. Используется, насколько я помню, для эффекта переворачивания машины после попадания в аномалию.

Часть вторая.
Как бы это использовать?

Для того, чтобы запустить тот или иной эффект из этой папки понадобится некоторое знание скриптов.
Эффекты запускаются с помощью операторов
level.add_cam_effector ("camera_effects\имя файла.anm", num, loop, "") - для эффектов камеры или анимаций

level. add _pp_effector ("имя файла.ppe", num, loop) - для постэффектов
num – любое четырехзначное число
loop - логическое значение: ставим либо true, либо false. Если true, то эффект будет проигрываться бесконечно, если false, то один раз.

Выглядеть это будет так.
Для примера возьмем выброс и все что с ним связано.
Запуск постэффекта выброса:

level.add_pp_effector("vibros.ppe", 1974, false)

запуск анимации землетрясения

level.add_cam_effector("camera_effects\earthquake.anm", 1975, false, "")

Как вы заметили, во втором случае, так как анимации в основном лежат в подпапке camera_effects нужно ее указывать. Если же анимка берется из общей папки anims, тогда нет.

Цифры после запятой это sid эффекта который мы ему задаем. Могут быть любыми – четырехзначными. Для чего – поясню ниже.
Для остановки эффекта используется два следующих оператора:
Для остановки эффекта камеры:

level.remove_cam_effector(num)

для остановки постэфекта:

level.remove_pp_effector(num)

Остановка двух наших предыдущих эффектов будет выглядеть так.
останавливаем выброс

level.remove_pp_effector(1974)

Останавливаем землетрясение

level.remove_cam_effector(1975)

Как вы могли заметить, в скобках вместо имен эффектов мы просто написали цифры – sid’ы эффектов, которые мы задали в запуске процессов. Так удобнее, нежели снова вписывать полное имя.

Простейший скрипт запускающий эффект, скажем выброса, будет выглядеть так:

function run_vibros()
level.add_pp_effector("vibros.ppe", 1974, false)
level.add_cam_effector("camera_effects\earthquake.anm", 1975, false, "")
set_postprocess ("scripts\earthshake.ltx")
end

Но это будет, во-первых безопасный выброс, во-вторых весьма кратковременный, а в третьих – беззвучный.
Для того, чтобы это исправить, добавляем в формулу вот это:
local h = hit ()
h.power = 1 --сила хита, регулируется по желанию
h.direction = vector():set( 1, 0, 0 ) --вектор получения хита
h.impulse = 1 --импульс
h.draftsman = db.actor --от кого дать хит
h.type = --тип хита
db.actor:hit (h) --кому дать хит

Тип хита можно задать самый разный.
Можно хитовать эктора только радиацией
hit.radiation
или телепатией
hit.telepatic
или шоком
hit.shock

В общем выбирайте любой по своему усмотрению.

Можно задать сразу несколько хитов.

function Run_Vibros()
local h = hit()
h.direction = vector():set( 1, 0, 0 )
h.impulse = 1
h.draftsman = db.actor
h.power = 1
h.type = hit.radiation
db.actor:hit(h)
h.power = 2
h.type = hit.shock
db.actor:hit(h)
h.power = 2
h.type = hit.telepatic
db.actor:hit(h)

Здесь эктор будет получать хит радиацией, шоком и телепатией.
Идем дальше. Звук.
После того как расписали, от чего эктору будет хреново и насколько хреново, добавляем в
скрипт эти строчки:
local snd_obj = xr_sound.get_safe_sound_object([[ambient\earthquake]])

snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 1.0)

--Все - звук выброса у нас есть.
--можно добавить еще звук счетчика Гейгера:
xr_sound.set_actor_sound("level_border_detector")
xr_sound.set_actor_sound_factor(0.1)

Вот еще набор пугающих звуков из папки sounds:
local snd_obj = xr_sound.get_safe_sound_object([[ambient\rnd_outdoor\rnd_dark4]])
local snd_obj = xr_sound.get_safe_sound_object([[ambient\rnd_outdoor\rnd_moan1]])
local snd_obj = xr_sound.get_safe_sound_object([[ambient\rnd_outdoor\rnd_moan2]])
local snd_obj = xr_sound.get_safe_sound_object([[ambient\rnd_outdoor\rnd_dark6]])

local snd_obj=xr_sound.get_safe_sound_object([[ambient\random\rnd_the_horror]])

--Погода из папки weathers
level.set_weather("stancia") \ погода на аэс

– или это - судный день или день гнева
level.set_weather_fx ("surge_day")

--можно всунуть эффект телепорта (белый экран)
level.add_pp_effector ("teleport.ppe", 2009, false)

--постэффект мертвой зоны:
level.add_pp_effector("dead_zone.ppe", 1001, false)

или вместо этого
--кругом радиация
level.add_pp_effector("radiation.ppe", 1974, false)

--эффект «эктору конкретно двинули»
level.add_cam_effector("camera_effects\fusker.anm", 1975, false, "")

--или вместо этого
--эктора шатает как пьяного
level.add_cam_effector("camera_effects\drunk.anm", 1978, false, "")

--и у него «белочки» в глазах
level.add_pp_effector("alcohol.ppe", 1976, false)
end

В общем, в одну функцию можно "зарядить" сколько угодно эффектов, главное не переборщить, так как некоторые похожие анимки или ppe могут наложиться друг на друга и получится какая-нить хрень. Так что с этим надо быть аккуратным.
Это первое. А второе то, что так никто не делает. В том смысле, что в одну кучу все не валит.
Тот же выброс по нормальному делается многофазовым. И вот тут в каждой фазе прописывается тот или иной набор эффектов – анимация, постэффект, звук. И для каждой фазы отводится своя длительность. По таймеру. Также расписывается поуровнево какой какой тип хита и какой силы будет получать эктор в зависимотси от локации. А дальше идет остановка всех эффектов соответствующими операторами. Но так как в этой формуле этого нет – весь эффект продлится только несколько секунд, ровно столько сколько длится каждая анимация. Некторые ppe требуют принудительной остановки.
Для того, чтобы сделать выброс так как это сделано в глобальных модах, требуется очень хорошее знание скриптов.
Сам я написать такой скрипт не смогу, поэтому пользуюсь готовым – из аддона Blowout к ОГСМ. Там вполне рабочий и симпатичный выброс.

А вы можете поэкспериментировать в описанными эффектами для собственного удовольствия. Или замутить с их использованием какую-нить прикольную скриптовую сценку.
Позднее я постараюсь дополнить вышеизложенное. Материал на данный момент находится на стадии работы и будет дополняться и исправляться. А пока все.
Если если ошибки - комментируйте - исправлю.

Добавлено (16.08.2011, 04:14:13)
---------------------------------------------
Типа справочка по С#
[spoiler]

Код:
Пока только обзор методов работы с файлами и строками.
Используемые пространства имен
using System;
using System.IO;

обзор методов класса FileStream
поддерживается произвольный доступ

--получить доступ к файлу
FileStream varname = new FileStream(@"D:\test\test.txt", режим открытия,[режим доступа - необязательно]);

--режимы открытия файла
FileMode.Open --открыть существующий файл
FileMode.CreateNew --создать новый файл. если такой уже есть то возникнет исключение
FileMode.Create --создать новый файл. если такой уже есть то будет стерт
FileMode.Append --открыть файл если он существует и установить указатель в конец файла. Если файла нет то создать новый.(несовместим с режимами FileAccess.ReadWrite и FileAccess.Read)
FileMode.OpenOrCreate --открыть файл если существует. Если нет то создать.
FileMode.Truncate --открыть существующий файл и обрезать до нулевой длины. (Типа стереть все.)

--режимы доступа к файлу --аргументы FileStream
FileAccess.ReadWrite -- открыть для чтения и записи
FileAccess.Read -- открыть для чтения
FileAccess.Write --открыть для записи

ПОБАЙТОВОЕ ЧТЕНИЕ
--установка позиции
varname.Seek(насколько сдвигать в байтах, точка отсчета)
--точка отсчета
SeekOrigin.Begin --установить точку отсчета в начало файла
SeekOrigin.Current --установить точку отсчета в текущую
SeekOrigin.End --установить точку отсчета в конец файла

long l = varname.Seek(0, SeekOrigin.End)-- получить длину файла в байтах

varname.Write(откуда, с какой позиции, сколько байтов) -- записать последовательность(массив) байтов в текущий поток
varname.WriteByte(num) -- записывает один байт. (перемещает указатель в потоке на кол-во записанных байтов)
varname.Read(куда, с какой позиции, сколько байтов) -- считать последовательность(массив) байтов из потока
varname.ReadByte() --считывает один байт. (переместить указатель в потоке на кол-во считанных байтов)
varname.Position --получить текущую позицию в потоке
varname.Lenght -- получить длину потока? Пока не знаю как правильно использовать.
varname.SetLenght --установить длину потока

--общие методы
varname.Flush()--записать данные из буфера
varname.Close(); --закрыть файл

СИМВОЛЬНОЕ ЧТЕНИЕ
классы StreamWriter и StreamReader
произвольный доступ не поддерживается
varname = new StreamWriter(filename) --открыть файл на запись. Если нет то создать
varname = new StreamWriter(filename, true\false) -- для чего bool че то забыл
varname = new StreamReader(filename) --открыть файл на чтение

varname.ReadLine(s) -- cчитать строку из текущего потока и возвратить ее как string. возвращает null если достигнут конец файла при чтении
varname.ReadBlock(куда, с какого символа, сколько символов)-- считать указанное кол-во символов
varname.ReadToEnd() --считать все символы до конца потока и возвратить их как одну string
varname.Peek() --возвратить следующий символ
varname.NewLine --

varname.WriteLine(s) --записать строчку
varname.Write(s) --записать фрагмент текста

--СТРОКОВЫЕ МЕТОДЫ
string strRep = str.Replace("подстрока", "шаблон"); --заменяет все вхождения указанной подстроки в строке на указанный шаблон
char[] a = str.ToCharArray() --преобразует строку в массив символов
string strUp = str.ToLower(); --возвращает эквивалент строки в нижнем регистре
string strLow = str.ToUpper(); --возвращает эквивалент строки в верхнем регистре
string strCop = string.Copy(str) --возвращает копию строки
string[] mass = str.Split(); --разделяет строку на элементы результат помещается в массив. Как ставить разделители?
string str = string.Join("^",mass); --читает массив строк и соединяет их в одну через любой разделитель. Результат помещается в указанный массив
string sub = str.Substring(index, len) --возвращает подстроку строки начиная с указанного стартового индекса длиной в len
string newstr = str.PadLeft(str.Length+10) --сдвигает строку вправо вставляя указанное число пробелов перед строкой. В общем методы для выравнивания.
string newstr = str.PadRight(str.Length+10) -- должно сдвигать строку влево вставляя указанное число пробелов после строки.

string newstr = oldstr.Remove(0, 5); --удаляет подстроку в указанном диапазоне
string newstr = oldstr.Insert(0, "новая подстрока"); --вставляет в указанную позицию( индекс) строки новую подстроку
int v = str.IndexOf("я"); --возвращает индекс первого вхождения подстроки в вызывающую строку
int m = str.LastIndexOf("я"); возвращает индекс последнего вхождения подстроки в вызывающую строку

int g = str3.IndexOfAny(new char [] {'я','а','б','в'}, 0, str3.Length); --возвращает индекс первого вхождения в строку одного из символов указанных в массиве.
Аргументы - массив, стартовый индекс, число позиций для проверки.

string newstr = str.TrimStart(new char[]{'м'}); --удаляет начальные вхождения указанных в массиве символов или символа перед строкой
string newstr = str.TrimEnd(new char[]{'м'}); --удаляет начальные вхождения указанных в массиве символов или символа в конце строки
оба метода могут вызываться без аргументов. Только зачем?

int res = str1.CompareTo(str2); -- Возвращает отрицательное значение, если вызывающая строка меньше строки str2,положительное значение, если вызывающая строка больше строки str2, и нуль, если сравниваемые строки равны.

int res = string.CompareOrdinal(str,str1); -- аналог CompareTo. Принимает два либо пять аргументов - работает быстрее первой.
другой вариант
int res = string.CompareOrdinal(строка первая, стартовый индекс,строка вторая,стартовый индекс, максимальное число сравниваемых символов); --

string str = string.Concat(str, str2); --соединяет произвольное число строк в одну
str.StartsWith("начало строки") --возвращает true если начало вызывающей строки совпадает с указанным шаблоном
str.EndsWith("конец строки") --возвращает true если конец вызывающей строки совпадает с указанным шаблоном
пример
string str = "начало строки конец строки"
if str.StartsWith("начало строки") & str.EndsWith("конец строки"))
{
Console.WriteLine("совпадает");
}
else
Console.WriteLine("не совпадает");

МЕТОДЫ ДЛЯ ИЗМЕНЕНИЯ ОБЪЕКТОВ ТИПА STRING

используется специальный класс StringBuilder позволяющий динамически изменять строки
так как вообще то в С# поддерживается принцип постоянства строк.

также используется namespace System.Text

System.Text.StringBuilder str = new System.Text.StringBuilder("я помню чудное мгновенье", 0, 10, 100);
аргументы - строка, стартовый индекс строки, длина подстроки, размер буфера. Без числовых аргументов по умолчанию вся строка, размер буфера 16 байт.
str.Append("передо мной явилась ты"); --добавляет в конец строки(либо согласно указанным параметрам в нужную позицию) новую часть.
str.Remove(индекс, кол-во символов); --удаляет подстроку согласно указанным аргументам - стартовый индекс, кол-во символов
str.Replace("мгновенье", "секунду"); --замена всех вхождений указанной подстроки\символа на шаблон
str.ToString() --преобразование числового значения в строковое

Пока неисследованный класс
класс System.Convert
//конвертировать массив 8-битовых чисел в строку
string s = Convert.ToBase64String(new byte[] { 0, 100 });
//конвертировать двоичные данные из строки обратно в массив чисел
Convert.FromBase64String(s);

Добавлено (16.08.2011, 04:15:07)
---------------------------------------------
[spoiler]Создание новых переходов между уровнями через скрипт.

Материал для модмейкеров. Переходы между уровнями можно создать и скриптом.
Методика существовала уже довольно давно, созданная товарищем sarthur.
Но из-за некоторых синтаксических ошибок в главной функции - работала неправильно.
Теперь благодаря исправлению скрипта камрадом singapur22 все приведено в порядок.

Так что пользуйтесь.

Что нужно сделать.
Первое.

Скопировать нижеприведенную функцию в чистый скриптовый файл.

function create_level_changer(
p_story_id, -- STORY_ID нового level_changer (понадобится нам позже)
p_position, -- вектор, координаты точки, в которой будет располагаться центр нового level_changer
p_lvertex_id, -- level_vertext_id - идентифицируют уровень, на котором будет создан level_changer
p_gvertex_id, -- game_vertext_id

p_dest_lv, -- level_vertex_id - идентифицируют уровень, на будет перебрасывать игрока
p_dest_gv, -- game_vertex_id
p_dest_pos, -- координаты точки, в которой на новом уровне окажется игрок
p_dest_dir, -- направрение взгляда игрока
p_dest_level, -- название уровня, например "L11_Pripyat"
p_silent -- следует задать 1, чтобы подавить вопрос о смене уровня




Все кому я нужен могут найти меня по этому адресу : #EGGO_TM в общем буду рад пообщаться )
# 44
Пятница, 19.08.2011, 21:53:35

Ранг: Разведчик
Сообщений: 367
Награды: 64
Репутация: 2435 Регистрация: 22.07.2011  

StalkerВлад, а что тебе щё нужно напиши может помогу у меня очень много статей на эту тему

Добавлено (19.08.2011, 20:09:13)
---------------------------------------------
[spoiler]Формат файлов постпроцессинга (ppe)
Вступление
Представляю на суд общественности результаты моих изысканий по формату файлов постпроцессинга (.ppe)
Нераскрытыми для меня осталось 6 переменных (переменные, которые я для себя назвал free, обязательно идут перед каждой триадой цепочек, управляющих цветом и 3 коэффициента, идут в каждом правиле после байта функции), но простенькие ppe-файлы можно делать и без них.
Вообще, оказалось, что возможности ppe были сильно мною переоценены (например тепловизор сделать с их помощью если и можно, то крайне проблематично). Основной недостаток - ppe можно применить только ко всему экрану, на отдельный обьект это не предусмотрено движком (даже стелс-режим кровососа реализуется подменой модели). Так что могу предложить только слегка улучшеный прибор ночного зрения.
Получилось так себе, просто убрал шумы, добавил яркости/контрастности, но зато теперь со включенным nv днем не побегаешь - засветка почти как на настоящем (как в кино показывают) и туман гораздо сильнее мешает, клубы тумана почти непрозрачны.
По поводу компилятора/декомпилятора, пришел к выводу, что фильтр постпроцесса изделие штучное, смысла в отдельных утилитах нет - я все анализировал, клепал, менял только с помощью блокнота и шестнадцатиричного редактора (кстати, выяснил, что при смене файла постпроцесса необязательно перезапускать сталкера и даже релоад делать ни к чему - изменения подхватываются при следующем выключении постпроцесса в данном случае nv).
При анализе ppe сильно помог тот факт, что постпроцесс существует в игре в текстовом и компилированом виде (кому интересно, копайте \gamedata\script\postprocess.script - полный разбор текстовых файлов написан обычным скриптом, там же, в самом конце функция main загружает погоду и файл постпроцессинга, сами файлы лежат \gamedata\config\scripts например proba.ltx). Компилированные ppe лежат в anims.

Практика
Итак, ppe-файл - это набор правил, как должен изменяться тот или иной параметр изображения во времени, всего этих параметров - 16 (названия взяты из текстовых версий, чтобы путаницы не было). В отличие от текстовой версии, цепочки должны идти только в этом порядке и их всегда должно быть только 16 (если игра вывалилась с сообщением в логах noise.grain cannot be zero, значит вы что-то пропустили).
Выбраная цветовая компонента умножается на коэффициент, то при параметре равным 1 чистый белый цвет останется белым, а чистый черный - черным, остальные преобретут компонентный оттенок.
• free1 - об этой переменной чуть ниже
• color_add_red
• color_add_green
• color_add_blue
Указанное значение принимается как база для данного цвета, то есть, если у данного пикселя значение цвета меньше указанного, то оно принимается как указанное, а если больше, то остается прежним. Следует заметить, что это единственный набор переменных, задирать значения в которых выше 0.5 не имеет смысла, 0.5 прибавляется где-то в дебрях движка.
• free2
• color_base_red
• color_base_green
• color_base_blue
Эта триада правил отвечает за вес цвета в сером/яркостном представлении и в обычном цветном режиме результат не виден. Но при увеличении правила gray становится ясно, что при например color_gray_red = -1 чисто красные компоненты становятся черными, 0 = остаются без изменений, 1 - чисто белыми:
• free3
• color_gray_red
• color_gray_green
• color_gray_blue
Переменная управляет величиной обратной насыщенности, то есть, чем больше gray (максимум +1) тем меньше насыщенность изображения:
• gray
Размытие изображения, при больших значениях (пробовал 25) начинаются косяки, портится нижняя часть, если долго стоять на месте:
• blur
Раздвоение изображения по горизонтали и вертикали соответственно. Значение указывается относительно экрана, то есть при 1 копии обьекта, первоначально находящегося в центре окажутся точно по краям:
• duality_h
• duality_v
• noise_intensity - интенсивность шума
• noise_granularity - размер зерна шума
• noise_fps - сколько раз в секунду шум должен пересчитываться
Файл всегда начинается с 01 00 00 00 - скорее всего это синатура, по которой движок определяет содержимое(кстати, у файлов anm, которые содержать анимацию камеры и похоже имеют ту же логику строения, что и ppe сигнатурой является 00 11 00 00 ).
Затем идет 4 байта неопределенной переменной, которую я для себя назвал free. Всего их 3. Эти переменные стоят только перед триадами, отвечающими за изменения цветов, обычно равны 7C 00 00 00, но есть небольшие вариации. Визуально определить, что меняется при изменении этой переменной я не смог, если кто совершит этот подвиг - вечная слава :)
Затем начинаются цепочки в перечисленном выше порядке. Цепочка начинается с 01 01 ХХ 00, где ХХ - число правил в данной цепочке. Если указано 01 01 00 00 (то есть цепочка с 0 правил, то данная цепочка в постпроцессинге не участвует и сразу после нее должна начинаться следующая цепочка). Основная ошибка, которую можно допустить - несоответствие реального числа правил с указаным в заголовке цепочки. Контроль, контроль, и еще раз контроль.
Каждая цепочка состоит из правил изменения переменной. Исходя из скрипта разбора текстовых версий можно предположить, что правил в цепочке не должно быть больше 16 (хотя возможно это только для текстовых).Совершенно необязательно, что этих правил в разных цепочках будет одинаковое количество или даже длиться они будут одинаковое время.
Правило содержит в себе всегда ровно 23 байта. Примерное описание -
9A 99 99 3E 00 00 A0 40 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
----------- ----------- -- ----- ----- ----- -----------------------
значение время ф k1 k2 k3
• значение - 4-байтная float переменная, обычно меняется от -1 до +1
• время - в секундах 4-байтная float переменная
• ф - функция, во всех ppe равна 00, но попробовал менять(не должна быть 04 - игра вылетает). 00,03 - синус, 01,05 - косинус, 02 - линейная, остальные значения игнорируются и правило перестает работать вообще.
• k1, k2, k3 - коэффициенты для функций вот с ними почти не разбирался, на линейную фунуцию изменений не выявил, на синус/косинус влияют очень сильно, но на поиск закономерности не хватило времени, по умолчанию равны 00 80 00 80 00 80
• остаток строки во всех файлах 00 80 00 80 00 80 00 80 - изменение визуально ничего не меняет, возможно зарезервировано для следующих версий.
Вот и все. Поле для работы как видите еще есть - коэффициенты k[1,2,3] и переменные free[1,2,3] - предлагаю общественности устроить мозговой штурм на них.
Напоследок мой файл ночного зрения с комментариями (для использования комменты удалить, шестнадцатиричный код загнать в WinHex и сохранить как anims\x.ppe(имя любое), и не забыть поправить config\misc\postprocess.ltx в нужной секции).
01 00 00 00 // сигнатура

// Цвета выкручиваем на максимум
7C 00 00 00 // free1
01 01 02 00 // color_add_red
00 00 80 3F 00 00 00 00 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
00 00 80 3F 00 00 00 41 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
01 01 02 00 // color_add_green
00 00 80 3F 00 00 00 00 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
00 00 80 3F 00 00 00 41 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
01 01 02 00 // color_add_blue
00 00 80 3F 00 00 00 00 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
00 00 80 3F 00 00 00 41 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80

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

6C 10 00 00 // free2
01 01 02 00 // color_base_red
CD CC CC 3D 00 00 00 00 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
CD CC CC 3D 00 00 00 41 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
01 01 02 00 // color_base_green
CD CC CC 3D 00 00 00 00 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
CD CC CC 3D 00 00 00 41 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
01 01 02 00 // color_base_blue
CD CC 4C 3E 00 00 00 00 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
CD CC 4C 3E 00 00 00 41 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80

// В сером режиме все красные обьекты - белым, синие и зеленые - черным

7C 00 00 00 // free3
01 01 02 00 // color_gray_red
00 00 80 3F 00 00 00 00 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
00 00 80 3F 00 00 00 41 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
01 01 02 00 // color_gray_green
00 00 80 BF 00 00 00 00 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
00 00 80 BF 00 00 00 41 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
01 01 02 00 // color_gray_blue
00 00 80 BF 00 00 00 00 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
00 00 80 BF 00 00 00 41 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80

// Полностью черно-белое изображение с учетом правил color_gray_*
01 01 02 00 // gray
00 00 80 3F 00 00 00 00 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80
00 00 80 3F 00 00 00 41 00 00 80 00 80 00 80 00 80 00 80 00 80 00 80

01 01 00 00 // blur

// Двоения в глазах не будет

01 01 00 00 // duality_h
01 01 00 00 // duality_v

// Шума не будет
01 01 00 00 // noise_intensivity
01 01 00 00 // noise_granularity
01 01 00 00 // noise_fps

Добавлено (19.08.2011, 21:52:14)
---------------------------------------------
Сложный квест на оборону лагеря
[spoiler]Ceйчac мы coздaдим cлoжный квecт нa oбopoнy лaгepя!
Чтo нaм пoтpeбyeтcя?
 system.ltx
 character_desc_escape.xml
 spawn_sections.ltx
 npc_profile.xml
Содержание

• 1 Coздaниe и пoдгoтoвкa фaйлoв
o 1.1 Инфoпopшны
o 1.2 Диaлoги
o 1.3 Инфo для квecтa
o 1.4 Пpoфили
o 1.5 Фaйл для cкpиптa
• 2 Зaпoлнeниe фaйлoв
o 2.1 Пpoфили
o 2.2 Дoбaвлeниe в ПДA
o 2.3 Инфoпopшны

Coздaниe и пoдгoтoвкa фaйлoв
Инфoпopшны
Зapeгиcтpиpyeм пycтoй фaйл для info_portions.
Oткpывaeм фaйл system.ltx, нaxoдим вoт этo - [info_portions]. Hyжнo дoпиcaть в кoнeц cтpoки files этoгo paздeлa, чepeз зaпятyю info_new.
B config/gameplay coздaeм фaйл c нaзвaниeм info_new.xml, в нeм пишeм этo:
<?xml version="1.0" encoding="windows-1251" ?>

<game_information_portions>


</game_information_portions>
Диaлoги
Зapeгиcтpиpyeм пycтoй фaйл для диaлoгoв
B system.ltx нaxoдим paздeл [dialogs] и пpoдeлывaeм тo, чтo дeлaли c info_portions - дoпиcывaeм в кoнцe cтpoки files - dialogs_new.
Coздaдим этoт фaйл в config/gameplay
Haзвaниe: dialogs_new.xml, a в нeм тaкaя cxeмa:
<?xml version="1.0" encoding="windows-1251" ?>
<game_dialogs>

</game_dialogs>
Инфo для квecтa
Зapeгиcтpиpyeм XML фaйл для квecтa:
Haxoдим в config/gameplay фaйл c нaзвaниeм game_tasks.xml, a в нeм пocлe #include "gameplay\game_tasks_by_vendor.xml" вcтaвляeм
#include "gameplay\tasks_new.xml"
Coздaeм фaйл в пaпкe gameplay c нaзвaниeм tasks_new.xml. B нeгo пoкa пиcaть ничeгo нe нaдo.
Пpoфили
Зapeгиcтpиpyeм фaйл c пpoфилями.
Дoпишитe в paздeл specific_characters_files (тaм гдe [profiles]) - new_profils_chareng
Coздaдим в пaпкe gameplay фaйл c нaзвaниeм new_profils_chareng.xml
B нeм пишeм:
<?xml version='1.0' encoding="windows-1251"?>

<xml>

</xml>
Фaйл для cкpиптa
Coздaeм в пaпкe gamedata/scripts фaйл c нaзвaниeм new_dialog.script.
Зaпoлнeниe фaйлoв
Пpoфили
Coздaдим пpoфили нaпaдaющиx нa лaгepь NPC.
Oткpывaeм фaйл: new_profils_chareng.xml и в нeм пишeм мeждy <xml> и </xml>:

<specific_character id="esc_bandit_ataka_1" team_default = "1">
<name>esc_bandit_ataka_1</name>
<icon>ui_npc_u_stalker_bandit_master</icon>
<bio>esc_bandit_novice_bio</bio>

<class>esc_bandit_ataka_1</class>
<community>bandit</community> <terrain_sect>stalker_bandit_terrain</terrain_sect>

<rank>81</rank>
<reputation>-67</reputation>

<snd_config>characters_voice\human_02\bandit\</snd_config>
<crouch_type>1</crouch_type>

<panic_treshold>0</panic_treshold>

<visual>actors\bandit\stalker_bandit_master</visual>
<supplies>
[spawn] \n
wpn_ak74u \n
ammo_5.45x39_fmj = 1 \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"
#include "gameplay\character_dialogs.xml"
</specific_character>

<!------------------------------------------------------------------------------------------>
<specific_character id="esc_bandit_ataka_2" team_default = "1">
<name>GENERATE_NAME_bandit</name>
<icon>ui_npc_u_stalker_bandit_4</icon>
<bio>esc_bandit_novice_bio</bio>

<class>esc_bandit_ataka_2</class>
<community>bandit</community> <terrain_sect>stalker_bandit_terrain</terrain_sect>

<rank>59</rank>
<reputation>-60</reputation>

<snd_config>characters_voice\human_01\bandit\</snd_config>
<crouch_type>1</crouch_type>

<panic_treshold>0</panic_treshold>

<visual>actors\bandit\stalker_bandit_4</visual>
<supplies>
[spawn] \n
wpn_fort \n
ammo_9x18_fmj = 1 \n
device_torch \n
wpn_bm16 \n
ammo_12x70_buck \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"
#include "gameplay\character_dialogs.xml"
</specific_character>


<specific_character id="esc_bandit_ataka_3" team_default = "1">
<name>GENERATE_NAME_bandit</name>
<icon>ui_npc_u_stalker_bandit_3</icon>
<bio>esc_bandit_novice_bio</bio>

<class>esc_bandit_ataka_3</class>
<community>bandit</community> <terrain_sect>stalker_bandit_terrain</terrain_sect>

<rank>32</rank>
<reputation>-56</reputation>

<snd_config>characters_voice\human_01\bandit\</snd_config>
<crouch_type>1</crouch_type>
<panic_treshold>0</panic_treshold>

<visual>actors\bandit\stalker_bandit_3</visual>
<supplies>
[spawn] \n
wpn_pm \n
ammo_9x18_fmj = 1 \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</start_dialog>
</specific_character>




<!------------------------------------------------------------------------------------------>
<specific_character id="esc_bandit_ataka_4" team_default = "1">
<name>GENERATE_NAME_bandit</name>
<icon>ui_npc_u_stalker_bandit_5</icon>
<bio>esc_bandit_novice_bio</bio>

<class>esc_bandit_ataka_4</class>
<community>bandit</community> <terrain_sect>stalker_bandit_terrain</terrain_sect>

<rank>81</rank>
<reputation>-67</reputation>

<snd_config>characters_voice\human_02\bandit\</snd_config>
<crouch_type>1</crouch_type>

<panic_treshold>0</panic_treshold>

<visual>actors\bandit\stalker_bandit_5</visual>
<supplies>
[spawn] \n
wpn_pm \n
ammo_9x18_pmm = 1 \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"
#include "gameplay\character_dialogs.xml"
</specific_character>

<!------------------------------------------------------------------------------------------>
<specific_character id="esc_bandit_ataka_5" team_default = "1">
<name>GENERATE_NAME_bandit</name>
<icon>ui_npc_u_stalker_bandit_4</icon>
<bio>esc_bandit_novice_bio</bio>

<class>esc_bandit_ataka_5</class>
<community>bandit</community> <terrain_sect>stalker_bandit_terrain</terrain_sect>

<rank>59</rank>
<reputation>-60</reputation>

<snd_config>characters_voice\human_01\bandit\</snd_config>
<crouch_type>1</crouch_type>

<panic_treshold>0</panic_treshold>

<visual>actors\bandit\stalker_bandit_4</visual>
<supplies>
[spawn] \n
wpn_pm \n
ammo_9x18_fmj = 1 \n
device_torch \n
wpn_bm16 \n
ammo_12x70_buck \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"
#include "gameplay\character_dialogs.xml"
</specific_character>


<specific_character id="esc_bandit_ataka_6" team_default = "1">
<name>GENERATE_NAME_bandit</name>
<icon>ui_npc_u_stalker_bandit_3</icon>
<bio>esc_bandit_novice_bio</bio>

<class>esc_bandit_ataka_6</class>
<community>bandit</community> <terrain_sect>stalker_bandit_terrain</terrain_sect>

<rank>32</rank>
<reputation>-56</reputation>

<snd_config>characters_voice\human_01\bandit\</snd_config>
<crouch_type>1</crouch_type>
<panic_treshold>0</panic_treshold>

<visual>actors\bandit\stalker_bandit_3</visual>
<supplies>
[spawn] \n
wpn_pm \n
ammo_9x18_fmj = 1 \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</start_dialog>
</specific_character>
Oткpывaeм фaйл: npc_profile.xml, и в нeм пишeм:

<character id="esc_bandit_ataka_1">
<class>esc_bandit_ataka_1</class>
<specific_character>esc_bandit_ataka_1</specific_character>
</character>

<character id="esc_bandit_ataka_2">
<class>esc_bandit_ataka_2</class>
<specific_character>esc_bandit_ataka_2</specific_character>
</character>

<character id="esc_bandit_ataka_3">
<class>esc_bandit_ataka_3</class>
<specific_character>esc_bandit_ataka_3</specific_character>
</character>

<character id="esc_bandit_ataka_4">
<class>esc_bandit_ataka_4</class>
<specific_character>esc_bandit_ataka_4</specific_character>
</character>

<character id="esc_bandit_ataka_5">
<class>esc_bandit_ataka_5</class>
<specific_character>esc_bandit_ataka_5</specific_character>
</character>

<character id="esc_bandit_ataka_6">
<class>esc_bandit_ataka_6</class>
<specific_character>esc_bandit_ataka_6</specific_character>
</character><;/xml>

Добавлено (19.08.2011, 21:53:35)
---------------------------------------------
[spoiler]Oткpывaeм '''spawn_sections.ltx''', и в caмoм кoнцe пишeм:

<ini>[esc_bandit_ataka_1]:stalker_trader
character_profile = esc_bandit_ataka_1
spec_rank = veteran
community = bandit
use_single_item_rule = off
can_select_items = off
custom_data = scripts\esc_bandit_ataka_1.ltx

[esc_bandit_ataka_2]:stalker_trader
character_profile = esc_bandit_ataka_2
spec_rank = veteran
community = bandit
use_single_item_rule = off
can_select_items = off
custom_data = scripts\esc_bandit_ataka_2.ltx

[esc_bandit_ataka_3]:stalker_trader
character_profile = esc_bandit_ataka_3
spec_rank = veteran
community = bandit
use_single_item_rule = off
can_select_items = off
custom_data = scripts\esc_bandit_ataka_3.ltx

[esc_bandit_ataka_4]:stalker_trader
character_profile = esc_bandit_ataka_4
spec_rank = veteran
community = bandit
use_single_item_rule = off
can_select_items = off
custom_data = scripts\esc_bandit_ataka_4.ltx

[esc_bandit_ataka_5]:stalker_trader
character_profile = esc_bandit_ataka_5
spec_rank = veteran
community = bandit
use_single_item_rule = off
can_select_items = off
custom_data = scripts\esc_bandit_ataka_5.ltx

[esc_bandit_ataka_6]:stalker_trader
character_profile = esc_bandit_ataka_6
spec_rank = veteran
community = bandit
use_single_item_rule = off
can_select_items = off
custom_data = scripts\esc_bandit_ataka_6.ltx
</ini>
===Лoгикa===
Oткpывaeм '''gamedata\config\scripts''' и тaм coздaeм 6 фaйлoв лoгики:

1-й фaйл лoгики - '''esc_bandit_ataka_1''', в нeм пишeм:
<ini>
[logic]
active = remark@search
on_death = death

[death]
on_info = %+esc_bandit_ataka_1_dead%

[remark@fire]
combat_ignore_cond = {!is_sniper_enemy}
radius = 0
anim = hide
on_info = {=health_le(0.5)}
remark@search
wounded = wounded@work
sniper = true

[remark@search]
combat_ignore_cond = true
combat_ignore_keep_when_attacked = false
anim = hide
target = actor
on_info = {=see_enemy}
remark@fire
wounded = wounded@work

[smart_terrains]
none = true

[wounded@work]
hp_state = 0|wounded_heavy@help_heavy
hp_state_see = 0|wounded_heavy@help_heavy
hp_victim = 0|nil
hp_fight = 0|false
hp_cover = 0|false
</ini>
Ocтaльныe фaйлы coздaютcя c aнaлoгичным coдepжaниeм, нo в нaзвaнии мeняeтcя цифpa нa cлeдyющyю и в
<ini>[death]
on_info = %+esc_bandit_ataka_1_dead%</ini>
тaкжe мeняeтcя цифpa нa нoмep cлeдyющeгo пpoфиля.
===Диaлoги===
Oткpывaeм '''dialogs_new.xml''', и в нeм пишeм мeждy <game_dialogs> и </game_dialogs>:
<xml><dialog id="esc_ataka_2">
<has_info>ataka_done</has_info>
<dont_has_info>ataka_ok</dont_has_info>
<phrase_list>
<phrase id="0">
<text>Boлк, нy ты кaк, жив?</text>
<next>1</next>
</phrase>
<phrase id="1">
<text>Дa, Xa-xa, кaк мы иx?</text>
<next>2</next>
</phrase>
<phrase id="2">
<text>Плoxo, дpyг мoй, плoxo...</text>
<next>3</next>
</phrase>
<phrase id="3">
<text>Boт cпacибo тeбe... Boт, дepжи, чeм бoгaт...</text>
<action>new_dialog.ataka_reward</action>
<next>4</next>
</phrase>
<phrase id="4">
<text>Cпacибo!</text>
<give_info>ataka_ok</give_info>
<action>dialogs.break_dialog</action>
</phrase>
</phrase_list>
</dialog>
<dialog id="esc_ataka_1">
<dont_has_info>ataka_start</dont_has_info>
<phrase_list>
<phrase id="0">
<text>Boлк, a чтo ты вecь дpoжишь?</text>
<next>1</next>
</phrase>
<phrase id="1">
<text>Дa c минyты нa минyтy бaндиты нaпaдyт...</text>
<next>2</next>
</phrase>
<phrase id="2">
<text>Я тeбe пoмoгy oтбитьcя, xopoшo?</text>
<next>3</next>
</phrase>
<phrase id="3">
<text>Boт cпacибo тeбe Meчeный, вeк бyдy блaгoдapeн!</text>
<next>4</next>
</phrase>
<phrase id="4">
<text>Xвaтит coпли pacпycкaть, c минyты нa минyтy бaндиты пoдoйдyт!</text>
<give_info>ataka_start</give_info>
<action>new_dialog.esc_bandit_ataka_1</action>
<action>new_dialog.esc_bandit_ataka_2</action>
<action>new_dialog.esc_bandit_ataka_3</action>
<action>new_dialog.esc_bandit_ataka_4</action>
<action>new_dialog.esc_bandit_ataka_5</action>
<action>new_dialog.esc_bandit_ataka_6</action>
<action>dialogs.break_dialog</action>
</phrase>
</phrase_list>
</dialog>
</game_dialogs>

Oткpывaeм character_desc_escape.xml ищeм
<specific_character id="esc_wolf" team_default = "1">
и пocлe
<actor_dialog>tm_wolf_reward</actor_dialog>
вcтaвляeм
<actor_dialog>esc_ataka_2</actor_dialog>
<actor_dialog>esc_ataka_1</actor_dialog></actor_dialog>

Дoбaвлeниe в ПДA
Oткpывaeм tasks_new.xml и в нeм пишeм:
<game_task id="ataka_bandit">
<title>Пoмoщь Boлкy</title>
<objective>
<text>Пoмoщь Boлкy</text>
<icon>ui_iconsTotal_kill_stalker</icon>
<infoportion_complete>ataka_ok</infoportion_complete>
</objective>
<objective>
<text>Oтбитьcя oт aтaки бaндитoв.</text>
<icon height="50">ui\ui_icons_task</icon>
<function_complete>new_dialog.bandit_atack_precon</function_complete>
<infoportion_set_complete>ataka_done</infoportion_set_complete>
</objective>
<objective>
<text>Пoгoвopить c Boлкoм.</text>
<map_location_type hint="Boлк">blue_location</map_location_type>
<object_story_id>Escape_novice_lager_volk</object_story_id>
<infoportion_complete>ataka_ok</infoportion_complete>
</objective>
</game_task>
Инфoпopшны
Oткpывaeм info_new.xml и мeждy <game_information_portions> и </game_information_portions> пишeм:
<info_portion id="ataka_start">
<task>ataka_bandit</task>
</info_portion>

<info_portion id="ataka_done"></info_portion>
<info_portion id="ataka_ok"></info_portion>

<info_portion id="esc_bandit_ataka_1_dead"></info_portion>
<info_portion id="esc_bandit_ataka_2_dead"></info_portion>
<info_portion id="esc_bandit_ataka_3_dead"></info_portion>
<info_portion id="esc_bandit_ataka_4_dead"></info_portion>
<info_portion id="esc_bandit_ataka_5_dead"></info_portion>
<info_portion id="esc_bandit_ataka_6_dead"></info_portion>
Oткpывaeм пaпкy gamedata/scripts, нaxoдим фaйл c нaзвaниeм new_dialog.script, a в нeм пишeм:

function esc_bandit_ataka_1()
alife():create("esc_bandit_ataka_1",vector():set(-141.80,-14.23,-123.79),107755,70)
end
function esc_bandit_ataka_2()
alife():create("esc_bandit_ataka_2",vector():set(-141.80,-14.23,-123.79),107755,70)
end
function esc_bandit_ataka_3()
alife():create("esc_bandit_ataka_3",vector():set(-141.80,-14.23,-123.79),107755,70)
end
function esc_bandit_ataka_4()
alife():create("esc_bandit_ataka_4",vector():set(-141.80,-14.23,-123.79),107755,70)
end
function esc_bandit_ataka_5()
alife():create("esc_bandit_ataka_5",vector():set(-141.80,-14.23,-123.79),107755,70)
end
function esc_bandit_ataka_6()
alife():create("esc_bandit_ataka_6",vector():set(-141.80,-14.23,-123.79),107755,70)
end


function bandit_atack_precon(task, info)
if (db.actor:has_info("esc_bandit_ataka_1_dead") and
db.actor:has_info("esc_bandit_ataka_2_dead") and
db.actor:has_info("esc_bandit_ataka_3_dead") and
db.actor:has_info("esc_bandit_ataka_4_dead") and
db.actor:has_info("esc_bandit_ataka_5_dead") and
db.actor:has_info("esc_bandit_ataka_6_dead")) then
return db.actor:give_info_portion("ataka_done")
end
return false
end

function ataka_reward(first_speaker, second_speaker)
dialogs.relocate_money(second_speaker, 10000, "in")
end

Bce, пoздpaвляю, вы нaпиcaли нoвый квecт! Oн бyдeт y Boлкa. Жeлaтeльнo eгo выпoлнять пocлe квecтa c флeшкoй Шycтpoгo!

В этой статье вы узнаете как создать спавнящийся физический объект.
Выбираем нужную модель из папки gamedata\meshes.
Создаем в файле misc\items.ltx (или своем конфиге) новую секцию, которая будет выглядеть так:

[vedro]:identity_immunities ;vedro — название спавн-секции предмета (Потом мы будем через него спавнить). Пишется латиницей.
$spawn = "dynamic_objects\el_tehnika\komp_klava" ;путь спавн-секции в дереве спавн-объектов в СДК (если не пользуетесь СДК, то особой важности не имеет).
visual = objects\dynamics\decor\vedro_01.ogf ;Путь до модели физического объекта из папки meshes.
cform = skeleton ; Движковые классы (донт тач)
class = P_SKELET
remove_time = 4 ;Время через которое объект исчезнет. Число до от 0 до 9999, если поставить 9999 то он просуществует очень долго

Второй вариант
[vedro]:identity_immunities ;vedro — название спавн-секции предмета (Потом мы будем через него спавнить). Пишется латиницей.
$spawn = "physics\object" ;путь спавн-секции в дереве спавн-объектов в СДК (если не пользуетесь СДК, то особой важности не имеет).
visual = objects\dynamics\decor\vedro_01.ogf ;Путь до модели физического объекта из папки meshes.
class = O_PHYS_S
remove_time = 60000 ;Время через которое объект исчезнет. Число до от 0 до 9999, если поставить 9999 то он просуществует очень долго.

Так вроде лучше )


Сохраняем файл.
Далее уже стандартно — создаем в скриптовом файле функцию типа
function spawn ()
alife():create("vedro",vector():set(координаты X,Y,Z),level_vertex_id,game_vertex_id)
end
И вызываем эту функцию через диалог или другой скрипт.
[spoiler]




Все кому я нужен могут найти меня по этому адресу : #EGGO_TM в общем буду рад пообщаться )
# 45
Вторник, 20.09.2011, 14:50:29

Ранг: Познающий
Сообщений: 103
Награды: 5
Репутация: 1059 Регистрация: 22.02.2010 Город: Моршанск    

Folin, Вот тебе статья по созданию спальника
http://stalkerin.gameru.net/wiki/index.php/SoC._Спальный_мешок


"strelok53" Ник защищен ©
# 46
Среда, 26.10.2011, 11:48:01

Ранг: Разведчик
Сообщений: 367
Награды: 64
Репутация: 2435 Регистрация: 22.07.2011  

вот вам ещё статейка

Добавлено (19.10.2011, 14:33:09)
---------------------------------------------
вот ещё одна про респавн

Добавлено (26.10.2011, 11:48:01)
---------------------------------------------
StalkerВлад,

Quote (StalkerВлад)
rd_team, как можно сделать локации с монстрами???
Добавлено (24.08.2011, 11:50:33)
---------------------------------------------
rd_team, только новые локации


как создавать берешь сдк и делаешь карту потом все нужные для нее конфиги ну а монстров потом можно через ал спавн заспавнить ну или скриптом а ещё проще через тот же сдк при создании



Все кому я нужен могут найти меня по этому адресу : #EGGO_TM в общем буду рад пообщаться )
# 47
Воскресенье, 15.07.2012, 21:24:19

Ранг: Прибывший
Сообщений: 1665
Награды: 95
Репутация: 4016 Регистрация: 03.03.2011  

Добавление статей в ПДА


---------------------------------------------
Спавн и удаление переходов между локациями скриптовым методом

# 48
Воскресенье, 07.07.2013, 12:37:14

Ранг: Прибывший
Сообщений: 7
Награды: 0
Репутация: 0 Регистрация: 10.02.2012 Город: Ейск    

Одинокий-Волк, реально ли на чистом тч с прикрученным фриплеем сделать респавн не только неписей, но и разных предметов (патроны, аптечки, арты ) через определенный промежуток времени?


Профессиональный сталкер. Знаю о Зон все. Ну или почти все.
# 49
Пятница, 04.10.2013, 16:22:30

Ранг: Новичок
Сообщений: 26
Награды: 0
Репутация: 55 Регистрация: 05.05.2012  

Динамическое снаряжение при старте
# 50
Пятница, 04.10.2013, 18:09:06

Ранг: Мастер
Сообщений: 1485
Награды: 139
Репутация: 2940 Регистрация: 13.07.2011 Город: Ново-Николаевскъ    

Цитата (modos)
весь код будет в скрипте items_start_random.script дабы не гадить в апдейте
А зачем вообще "гадить в апдейте", в итоге, эта фукция будет проверяться всю игру.
Т.к. функция нужна всего лишь раз и при начале игры, не лучше ли будет вызывать функцию при старте игры?
# 51
Понедельник, 21.10.2013, 16:38:03

Ранг: Новичок
Сообщений: 26
Награды: 0
Репутация: 55 Регистрация: 05.05.2012  

Цитата Callisto ()
А зачем вообще "гадить в апдейте"

Ну не большая нагрузка на движок, ну можно в разные места записать, можно через рестриктор даже, через можно также в скриптах в net_spawn в бинде ну в общем много где можно. А так нагрузка на двиг не большая совсем :)

Не злоупотребляй чрезмерным цитированием.
Устное предупреждение.
comador


Сообщение отредактировал comador - Понедельник, 21.10.2013, 23:40:45
# 52
Понедельник, 21.10.2013, 21:01:50

Ранг: Мастер
Сообщений: 1485
Награды: 139
Репутация: 2940 Регистрация: 13.07.2011 Город: Ново-Николаевскъ    

Цитата modos ()
А так нагрузка на двиг не большая совсем
Только потом, у начинающих модмейкеров, из-за кучи таких мелочей получаются глючные моды ;)




Сообщение отредактировал Callisto - Понедельник, 21.10.2013, 21:02:47
# 53
Суббота, 05.04.2014, 08:26:28

Ранг: Новичок
Сообщений: 37
Награды: 0
Репутация: 0 Регистрация: 17.11.2013 Город: Курган    

восстановил зомби и заспавнил их через скрипт

Expression : fatal error
Function : CScriptEngine::lua_error
File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp
Line : 73
Description : <no expression>
Arguments : LUA error: ...я мой мод\gamedata\scripts\sim_statistic.script:12: attempt to index global 'xr_statistic' (a nil value)


НАТО - это слово которое обозначает: Америка говно, а Россия лучшая страна в мире потому что русский воин победит любого!
# 54
Суббота, 05.04.2014, 10:21:29

Ранг: Прибывший
Сообщений: 1665
Награды: 95
Репутация: 4016 Регистрация: 03.03.2011  

Mecheniy12, "данные" о зомби добавил в xr_statistic.script?


Не столь важно что ты делаешь, важно как ты это делаешь! (Джимми Лансфорд)
Форум настоящего сталкера » S.T.A.L.K.E.R. Тень Чернобыля » Теория модостроения » Маленькие уроки по модостроению
  • Страница 3 из 3
  • «
  • 1
  • 2
  • 3
Поиск:
Вверх
Правила чата
Мини-чат
+Мини-чат
0