Logic
From Mod Wiki
Flag system
Waypoints can have flags modifying a character's behavior. Flags are set right in the waypoint's name. For instance, for the point named "wp00": wp00|flag1|flag2.
path_walk, path_look
Flags for path_walk waypoints:
- a=state
- Chooses body state for movement
- The list can be found in gamedata\scripts\state_lib.script.
- p=percent
- Probability of stopping at the point as a percentage (0-100). It is 100 by default. That is, the character never passes the point by.
- sig=name
- Set signal with the given name on arrival at the point (before turning) for the following check with the logic system field on_signal. To set a signal after turning, use the corresponding flag for a path_look waypoint.
Flags for path_look waypoints:
- a=state
- Chooses body state for standing (or sitting) at the spot.
- The list can be found in gamedata\scripts\state_lib.script.
- t=msec
- time in milliseconds to look at the point
- '*' means unlimited time. Valid values are in the range [1000, 30000], 5000 by default.
- For terminal waypoints of path_walk that have no more than one corresponding path_look, the value of t is always considered infinite and does not have to be set.
- sig=name
- Set the signal with the given name after turning towards the point.
- syn
- This flag will halt setting the signal until all characters with the given team arrive. The team is set as a text string in customdata. The given character will be play its idle animation until the others arrive.
- sigtm=signal
- Sets a signal when the time_callback is called by the state manager. If t=0, then the signal will be set after playing the init animation. This is used, for instance, with the press animation, which consists of two parts: 1 — pressing the button, 2 — lowering the arm.
- path_look can do: wp00|a=press|t=0|sigtm=pressed.
- Then switch the scheme: on_signal = pressed | other_scheme.
Paths in-depth
Configuration
For each walker, you should place onto the map:
- path path_walk, used to walk along
- path path_look, consisting of points to look towards
There can be one or more walkers. They can act independently, or interract with each other.
[walker]
- team
- team name — an arbitrary text string. All walkers in a team must have the same team. It is desirable to specify level name and location in team; for instance: escape_bridge, escape_factory — this will reduce the chance of error of giving different teams the same name.
- path_walk
- name of the path described in "1"
- path_look
- (optional) name of the path described in "2". If a character needs to only walk along a path, path_look can be ommitted. If a character should stand at places, it needs a path_walk point and at least one path_look point.
The rules for setting flags with examples:
Example 1
A character patrols territory around two houses. Here is how the route is made:
What to do to make the character run or sneak between certain points? There are flags in path_walk just for this purpose.
Each waypoint has a name: wp00, wp01, etc.
Flags are set in the name. They should be separated from the name using the symbol '|'. Write a=anim, where anim is the name of an animation from 2.4.4 of original documentation. If we write a=thread, the character will enter danger mode, if a=raid will run with his weapon at ready, etc.
Note: only animations from the "walk states" section can be used!
Example 2
A character conversation.
To make a character speak while moving along a path, each point must have a list of topic he can speak about. There is the following field for this: s = sound_scheme_name (off by default). Several topics can be separated by commas.t
Example 3
Example 3 uses only the field s to set conversation topics.
It is NOT RECOMMENDED to set the other parameters (sp, sf, st). The default values are acceptable for most scripts.
It is also NOT RECOMMENDED to use the parameter sa. If a sound must be run at the same time as an animation, you should use fields in path_look, which will be described later in this document.
If a character not only walks along the path, but must also stop and play animations, you should set the path_look path.
Example 4
Improve Example 1, so that when the character passes a space between houses, stopped and looked inside it:
What is new? There is now a path_look path with two points. It is recommended to remove the link between these two points of the path in the editor right away, since it is not used anyway.
Forethermore, lets set some flags at the points of path_walk and path_look that are circled with a dashed line. For instance, in the upper pair of points, set the flag 0, and in the lower pair — flag 1.
Now the character will stop at points of path_walk marked with a flag, look towards the point of path_look marked with the same flag.
If a point of path_walk is not marked with a flag, the character will pass it without stopping.
One point of path_walk can correspond to several points of path_look. If this is the case, the character will randomly choose one of the suitable points.
Similarily to path_walk you can use various flags in points of path_look to modify behavior:
- p = 100
- Probability with which the character will look at that point. The values of all suitable p are added, so if one point has p = 100 and another 300, the character will look twards the point with probability 25% (100 out of 100 + 300).
- To avoid confusion, you should set p such that they add up to 100.
- By default, all points have p = 100.
- t = time in milliseconds
- Duration of time for which the character will stop at this point.
- By default, the value is 5000.
Example 5
In this example, as the character passes point wp00, he will look at the point wp00 for 5 seconds with probability 30% or at the point wp01 for 10 seconds with probability 70%.
By default, the character plays the idle animation when he stops if he is not crouching, or animation hide if he is crouching.
If you need a different animation, you can set it with this flag:
a = animation name (defaults to idle).
Write a=anim, where anim – is the name of an animation from 2.4.4. of the actual documentation. If we write a=hide, the character will enter the alert mode, if a=guard, will stand with his weapon on ready, etc.
- Note: You can only use animations from the section "standing and crouching animations" for path_look!
Stalker behaviour schemes
There is a certain set of schemes that describe a character's behavior. They are set in his custom_data or, in case of a gulag, in corresponding flags, describing the function of a given gulag. The list of these scheme follows.
All of the loaded schemes are listed in the file \gamedata\scripts\modules.script
walker scheme
This is the basic scheme that moves a character along waypoints (path_walk) and stops at certain points and executes certain actions.
[walker]
- path_walk = <path name>
- the main path the NPC traverses
- path_look = <path name>
- path the NPC looks towards
- team
- team to synchronize
The characters stops and looks at a certain points at path_walk points with corresponding path_look points, while playing (or not playing) a certain animation.
- def_state_moving1
- state in which the NPC moves towards the first point if it is nearby (patrol by default)
- def_state_moving2
- state in which the NPC moves towards the first point if it is further (rush by default)
- def_state_moving3
- state in which the NPC moves towards the first point if it is far away (sprint by default)
- def_state_standing
- default state in which the NPC stands at the point and looks, unless a different state is specified for the point
File: \gamedata\scripts\xr_walker.script
remark scheme
This scheme is used for synchronization and binding with other schemes.
[remark] snd_anim_synс = true либо false. По умолчанию false. Указывает на то необходимо ли синхронизировать звук с анимацией либо нет
- snd
- remark sounds; nil by default
- anim
- remark animation; wait by default
- target
- where the stalker looks; there are the following options
- story_id
- a number
- actor
- no comment
- nil
- position automatically calculated by the AI
- <job name>, <gulag name>
- look at a stalker that has a certain job in a certain gulag (the second parameter is not required, if omitted, the gulag of the stalker to which the given section applies is used). Example:
target = logic@cit_killers_base_guard, cit_killers
- <path name>, <point number>
- you can tell him to look at a vertex of a patrolling path
Note: that if this value is not set, it will be equal nil not actor. If you want to make a character look at an actor in a remark, you have to specify it explicitely. Given nil the character will return to an AI-calculated position.
Standard signals for remark:
- sound_end
- when the sounds finish playing
- anim_end
- when the animations finish playing
- action_end
- when both finish, if synchronized
An example of using animation and sound in a remark scheme:
[remark] anim = animation snd = sound snd_anim_sync = true on_signal = action_end | next scheme
sleeper scheme
Scheme for a sitting or slipping NPC. It must have a path consisting of at least one waypoint. The sleeper will sit down at the zeroth point of the path and face in the direction of the first point.
[sleeper]
- path_main
- path name
- wakeable = true
- whether the character can wake up quickly (if true, he will sleep squatting and will mumble in his sleep)
If the path constsists of two points, there should be a link from the first to the zeroth (or a bidirectional one).
File: \gamedata\scripts\xr_sleeper.script
kamp scheme
Scheme for a stalker sitting in a given radius from a given point (by a campfire) and facing this point.
[kamp]
- center_point = kamp_center
- name of the point at which the NPC will be dislocated
- radius = 2
- how far the NPC will be from the camp center; 2 by default
- def_state_moving = run
- default state in which the stalker will go towards the point
File: \gamedata\scripts\xr_kamp.script
If the camp point is inside a campfire, then in offline mode stalkers will approach it, then in online mode they will be inside the fire and will be damaged. To avoid this, in the camp section set path_walk from a point called <path_camp_name>_task.
path_walk = <path_camp_name>_task
If the camp point is located in an open field, then there is no need for adding path_walk.
camper scheme
Camper properties:
- кемпер стоит на точке и смотрит в направлении, куда Вы его поставили в редакторе или передигается по патрульным путям
- кемперы переключаются на универсальный комбат, только если видят врага ближе чем в 30 метрах. Если он выжил, он возращается в состояние кемпера.
- В любых других случаях действуют по собственной скриптовой схеме. Если видим врага -стреляем. Если слышим дэнжер - то смотрим в направление в данжере. Если видим гранату - убегаем от гранаты. Если видели врага, а враг исчез, то смотрим в точку, где видели последний раз врага.
- кемперы не сражаются в движении. Если они видят врага - они останавливаются, стреляют, а потом продолжают движение.
[camper]
- path_walk - patrol_path
- path_look - patrol_path
- radius - number – расстояние в метрах, если расстояние между кэмпером и противником меньше указанного, кэмпер уходит в универсальный комбат. По умолчанию этот радиус равен 20 метрам.
- no_retreat - true - персонаж при виде врага не будет ломиться на ближайшую точку path_walk, а сразу перейдет в режим убивания. Нужно это в том случае, если вы хотите сделать сценку, когда одни ребята наезжают на других. Ставите кемперов с вышеуказанным флажком. Они идут по своим патрульным путям и выносят врагов.
- def_state_moving - состояние из стейт менеджера. Состояние, в котором мы движемся на ближайшую точку пути при враге
- def_state_moving_fire - состояние из стейт менеджера (sneak_fire). Состояние, в котором мы отстреливаемся от врага, во время движения на ближайшую точку пути.
- def_state_campering - состояние из стейт менеджера (hide). Состояние, в котором мы ожидаем врага, находясь на пути
- def_state_campering_fire - состояние из стейт менеджера (hide_fire). Состояние, в котором мы отстреливаемся от врага, находясь на пути
- attack_sound - имя_звуковой_темы. Возможность переопределять снайперам/кемперам звук атаки. По дефолту он равен звуковой теме "fight_attack". Можно изменить на любое другое (для сценических потребностей) либо вообще отключить, прописав в секции кемпера: attack_sound =
- shoot - type
Задаем тип стрельбы. Возможные значения - always|none|terminal
- always - значение по умолчанию, стреляет всегда, когда можно
- none - не стреляет вообще.
- terminal - стреляет только когда находится на последней точки патрульного пути. Это сделано для облегчения построение атакующих сцен.
У кемпера есть один большой минус – когда ему наносится хит и он не знает откуда хит наносится (не видит противника, не слышит выстрела), то он тупо продолжает стоять на старом месте и ждать следующей пули. Ввиду этого не стоит расставлять кемперов в случае, когда сталкеры должны защищаться и держать позицию в том случае, если есть несколько направлений, откуда игрок или стелкеры смогут атаковать поставленного кемпера. Используйте walkerов в таких случаях, а кемперов стоить ставить для атак по путям и как снайперов.
sniper scheme
A variety of camper. Differs by shooting only single shots and not looking along patrol points, but rather scanning space between them. Scan speed between two points is fixed at 20 seconds. Note: set only two look points for a sniper.
Write the following in custom data:
sniper = true
File: \gamedata\scripts\xr_camper.script
follower scheme
В custom_data прописан как follower NPC идет за NPC лидером. Если до лидера расстояние менее 5 метров, то он идет, если от 5 до 20 – бежит в режиме run, если свыше 20 – догоняет в режиме sprint. Пути не задаются.
[follower]
- leader - story id лидера из game.ltx (число!)
- formation_line - true (постарается идти сбоку от лидера, в противном случае будет идти сзади
- distance - расстояние в метрах, на котором будет идти от лидера attendant. По умолчанию – 1,5 метра, если идет цепью, то 5 метров.
- state_if_leader_in_meet - Это есть строка с именем состояния из state_manager, которое будет назначено follower-ам, если командир пребывает в состоянии meet.
- anim_walk - state (состояние, в котором фолловер идет за лидером)
- anim_run - state (состояние, в котором фолловер бежит за лидером)
- anim_sprint - state (состояние, в котором фолловер спринтует за лидером)
File: \gamedata\scripts\xr_ attendant.script
Если все это происходит под гулагом, то вместо story_id лидера, мы прописываем его секцию логики в файле скрипта. Example:
t = { section = "logic@bar_arena_follower_2", idle = 0, prior = 7, state = {0}, squad = squad, group = groups[0], in_rest = "", out_rest = "", dependent = "logic@bar_arena_leader", predicate = function(obj) return obj:character_community() == "dolg" end }
zoneguard scheme
There are two zones for the NPC (or one). He walks along paths, but when the player enters the first zone, drops everything, runs up to the player, points a weapon at him (might also yell or talk), if the player enters the second zone — attacks him
[zoneguard]
- path_walk
- path_look
- team
- name of a team of synchronized zoneguards (only one from the team will react to the player)
- zone_guard
- the name of the zone in which the player will be attacked
- zone_warn
- the name of the zone in which to start a conversation with the player
- walker_team
- team to set it in walker mode (will be the same as team if not set)
- no_move
- will yell to the player from the spot, and not run towards him
- snd_greet
- name of the sound scheme from which to play a sound on finding the player
- ignore_friends
- if true, will ignore friendly characters
- ignore_cond
- {+info -info =func !func} conditions for ignoring the player
- no_danger
- if true, will not play the threat animation to neutrals
- anim
- animation to play if not hostile to the player
- snd_anim_sync
- if true, will synchronize sound with animation
File: \gamedata\scripts\xr_zoneguard.script
wounded scheme
[logic] wounded = wounded [walker] wounded = wounded [wounded] hp_state = HP|condstate@condsound|HP|condstate@condsound hp_state_see = HP|condstate@condsound|HP|condstate@condsound psy_state = PSY|condstate@condsound|PSY|condstate@condsound hp_victim = HP|condvictim|HP|condvictim hp_cover = HP|condbool|HP|condbool hp_fight = HP|condbool|HP|condbool *syndata = state@sound|state@sound *help_dialog = story_id *help_start_dialog = story_id
Where:
- Condstate
- condition list returning the character's state, or true. The NPC will become mad at the player if true is returned.
- Condsound
- condition list returning the sound scheme
- HP
- health point bounding values
- PSY
- psychological state boundary values
- Condvictim
- condition list returning the direction to look at. Possible values: nil, actor, number. In case of a number, will look at the player with the corresponding id.
- Condbool
- condition list returning true or false
Field values:
- hp_state
- character's behavior in absense of the player in site
- hp_state_see
- character's behavior on seeing the player
- psy_state
- character's behavior on psy attacks
- hp_victim
- point to look at depedning on HP
- hp_cover
- go to cover or not, based on HP
- hp_fight
- combat allowed or not, based on HP
- syndata
- synch pairs, for effect
- help_dialog
- story_id of a dialog to use instead of teh default actor_help_wounded. If the plot demands that you replace this dialog with another, you specify the id in this field.
- We also add a dialog for the wounded. If we set it, all actor's dialogs for the wounded should have this precondition: dialogs.allow_wounded_dialog.
The default settings for example:
hp_state = 30|help_me@help|10|wounded_heavy@help_heavy hp_state_see = 30|wounded@help_see|10|wounded_heavy@help_heavy psy_state = 50|{=best_pistol}psy_armed,psy_pain@wounded_psy|20| {=best_pistol}psy_shoot,psy_pain@{=best_pistol}wounded_psy_shoot,wounded_psy hp_victim = 30|actor|10|nil hp_cover = 30|true|10|false hp_fight = 30|true|10|false syndata = wounded@help
Where:
- Best_pistol
- a check to make sure the NPC's best weapon is not a pistol
File: \gamedata\scripts\xr_wounded.script
rest scheme
The dude walks, eats, sleeps.
Does not really work yet.
File: \gamedata\scripts\xr_rest.script
heli_hunter scheme
Helihunter might shoot or not shoot at a helicopter, depending on conditions. This is how it works:
[camper@bar_freedom_attack_sniper_1] path_walk = camper_1_walk path_look = camper_1_look on_info = {+bar_freedom_attack_ecolog} camper1@bar_freedom_attack_sniper_1 %= bar_freedom_angry_actor% meet_talk_enabled = true meet_dialog = bar_svoboda_dialog heli_hunter = {-bar_ecolog_crush_heli_down} true, false
patrol scheme
Here is a preliminary patrol system. It is a variety of kamp, except in walking mode. To make it work, add the following to custom data:
[patrol]
- path_walk = path_walk
- path_look = path_look
- formation = back
- describes the formation type, and is required. Can be one of the following
- back
- line
- around
- commander = true
- sets the commander; there should be only one
- move_type = patrol
- sets the initial movement mode, patrol by default. This value is a walking animation from state_mgr_lib
When the commander stops at meet, the guys stop
If the commander dies, another one is chosen automatically. The first to enter the scheme is chosen. Formation at waypoints is done like this:
- ret=0...2
- 0 - line
- 1 – around
- 2 – to the sides
When the commander moves, he works like a regular walker, and the others follow his actions. That is, if the waypoint is set to a=assault, the commander will rush forward with his weapon at ready, and the others copy him.
What does not really work:
- there is no way to modify formation
- everyone is quiet
- commander does not give commands
- it is not recommended to use sprinting
Sections
combat section
Показывает, что происходит, когда NPC срывается в бой. on_combat = combat
[combat] on_info = %+info -info =func% эффекты, которые вызываются на каждом раунде боя.
Для задания различных типов скриптовых боёв для различных ситуаций используется параметр combat_type.
В следующем примере сталкер сражается:
- по-кемперски, если враг=актёр и он дальше Х метров
- по-монолитовски, если любой враг дальше Y метров
- иначе - движковый бой
[logic] active = walker on_combat = combat [walker] path_walk = ... [combat] combat_type = {=fighting_actor =fighting_ge_X_meters} camper, {=fighting_ge_Y_meters} monolith
Пример такой функции: нам надо чтобы на расстоянии свыше 20 метров npc переходил бы в кемперский комбат. function fighting_dist_ge_20(actor, npc) return db.storage[npc:id()].enemy:position():distance_to ( npc:position() ) >= 400 end 400 – это 202 . Примечание – мы пишем квадрат нужного нам расстояния, для экономии системных ресурсов.
Ещё один пример. Сталкер ходит под симуляцией, но у него бой не движковый, а всегда зомбированый:
[logic] active = nil on_combat = combat [combat] combat_type = zombied
Если в разных секциях для персонажа требуются разные типы боя или разные условия, то можно воспользоваться оверрайдом combat_type. Помните: оверрайд всегда будет перекрывать настройку в секции combat. Т.е., если у вас логика на 5 секций и в четырёх нужен кемперский комбат, а в пятой монолитовский, то можно задать так:
[logic] active = walker1 on_combat = combat [walker1] ... [walker2] ... [walker3] ... [walker4] ... [walker5] ... combat_type = monolith [combat] combat_type = camper (scheme - задает тип боя (monolith, camper, zombied), иначе - универсальный бой)
disable_combat_handler – функция отключающая секцию combat. File: \gamedata\scripts\xr_combat.script
death section
The section shows what happens when an NPC dies.
on_death = death
[death] on_info = %+info -info =func%
File: \gamedata\scripts\xr_death.script
hit section
Shows what happens when an NPC is damaged. Note that on_hit does not react to the sound of a shot, but only a direct hit! This is done, because the sound of a shot should not be percieved as aggression in general (the player might be shooting dogs, but ending up provoking guards, for example).
on_hit = hit
[hit] on_info = %+info -info =func%
File: \gamedata\scripts\xr_hit.script
actor_dialogs section
Shows which dialogs will be available to the player when speaking with this NPC. Can be used in almost any scheme.
actor_dialogs = actor_dialogs
[actor_dialogs]
- id
- comma-separated list of available dialogs
- disable
- comma-separated list of disbled dialogs
File: \gamedata\scripts\xr_meet.script
use section
This section shows what will happen if the player tried to "use" the NPC.
on_use = use
[use] on_info = %+info -info =func%
File: \gamedata\scripts\xr_use.script
combat_ignore section
If an NPC is in this scheme, then he enters into combat mode. In any other scheme:
[walker]
- combat_ignore_cond = {+info –info =func !func}
- condition for ignoring combat (if you write always then the character will always ignore combat in this schema, untill switching to a scheme that does not ignore combat)
There are no additional fields in the scheme:
[walker]
- combat_ignore = combat ignore
[combat_ignore]
Functions used for wark with the combat ignore condition list:
- fighting_dist_ge_20
- current enemy at distance equal to or greater than 20 m
- fighting_dist_ge(distance in meters)
- all-purpose function for combat_ignore, checks for distance from the player
- fighting_actor
- is actor the current enemy?
- check_fighting
- check (by story_id) to see if anyone from the list is an enemy
File: \gamedata\scripts\xr_combat_ignore.script
dont_spawn_character_supplies section
If this section is set, then the standard set of loot specified in the profile won't span inside him.
[dont_spawn_character_supplies]
no_smart section
If this section is present, the NPC cannot be controlled by the smart terrain, even if it fits all the parameters.
[no_smart]
treshhold section
There is a way to change stalkers' parameters that determine how they attack monsters. There are two such patameters:
- max_ignore_monster_distance
- (currently 15 m by default). The stalker will always attack monsters within a certain radius.
- ignore_monstre_threshold
- (currently 0 by default) Parameter 0 to 1. If the monster is evaluated at below this parameter, and the monster is outside the given radius, it will be attacked. Currently, stalkers never attack anything outside the 15-meter radius.
In the logic section or in the current sheme set:
threshold = threshold@tratata [threshold@tratata] max_ignore_distance = <number> ignore_monster = <number>
Be very careful about changing the second parameter.
Danger section
Настройка может задаваться только в какой-то схеме, например:
[walker] danger = danger_condition
[danger_condition] ignore_distance = 50 (расстояние указывается в метрах) ignore_ distance_grenade = ignore_ distance_corpse = ignore_ distance_hit = ignore_ distance_sound =
Можно также указывать время ожидания для денжера в зависимости от типа:
danger_inertion_time_grenade = danger_inertion_time_corpse = danger_inertion_time_hit = danger_inertion_time_sound =
Дефолтовые настройки: danger_inertion_time_grenade = 20000 danger_inertion_time_corpse = 10000 danger_inertion_time_hit = 60000 danger_inertion_time_sound = 15000
NB!!Также эти настройки теперь распространяются и на схему кемпера. То есть в настройках кемпера перестало работать поле danger_radius. Теперь данные берутся из секции денжера согласно общих правил.
Алгоритм работы такой: Сперва проверяется, что расстояние до опасности не отсекается по ignore_danger. Если опасность ближе, то тогда анализируется ее тип, и проверяется по соотвествующему данному типу расстоянию. Если опасность ближе - тогда разрешается реакция на нее.
В данный момент установлены следующие дефолты:
- ignore_distance = 50
- ignore_distance_grenade = 15
- ignore_distance_corpse = 10
- ignore_distance_hit = 50
- ignore_distance_sound = 50
NB: если надо, чтобы в разных случаях сталкер игнорировал разные типы данжеров, создается несколько секций данжера danger_condition@1, danger_condition@2 и так далее.
- danger_expiration_time = Через сколько времени денжер перестанет быть акутальным. Дефолт 5000 мс.
- danger_inertion_time = Через сколько времени персонаж забудет про денжер, на который он отреагировал. Дефолт 10000 мс.
stories section
Из нового: теперь лагеря автоматически рассказывать истории не будут. Для этого вы должны того или иного сталкера "научить" истории. Делается это так: в кастом дате пишется секция:
[game_info] stories = "story_01, legend_01"
В кавычках список историй и легенд через запятую. Пока что существуют следующие истории и легенды:
story_01 - Граница зоны и граната за 1 действие. story_02 - Про трамплин и про камешки story_03 - Про то как группа Вильнова вернулась story_04 - Про то как Костя Федорин наткнулся на артефакт и пропал на радаре. story_05 - Про то как духманам с контролером стражаться. story_06 - Про дверцу, водку и избушку. legend_01 - Про эксперимент в Зоне, который производят инопланетяне. legend_02 - Об особо засекреченных лабораториях в зоне. legend_03 - Легенда о проводнике legend_04 - Легенда о темном сталкере legend_05 - Легенда о том что глубоко в Зоне спать нельзя.
О том какие истории и легеды в каком лагере на каком уровня можно и нельзя юзать узнавать о Профа.
dont_spawn_loot section
Всякого рода сюжетные персонажи которые должны быть пустыми после смерти (например раненные или пленные) оказываются не пустыми. Чтобы это исправить необходимо в кастом дате персонажа прописать секцию [dont_spawn_loot]
Overrides
Settings that modify behavior of general schemes, depending on the currently active scheme (all optional).
- meet_enabled = true
- fire a flare for a metting
- meet_talk_enabled = true
- adds a possibility of a dialog to the current scheme
- meet_dialog = <dialog name>
- dialog to fire on use
- meet_state = <state name>
- sets the character's state for when a dialog opens
- wounded_enabled = true
- enables the NPC to use the wounded scheme
- combat_ignore_cond
- see above
- combat_ignore_keep_when_attacked = true
- the character ignores combat, even if shot at (but only if shot at by the player!)
- combat_type = {condition} scheme
- combat type to be used NPCs from this scheme
- on_combat
- see above
- companion_enabled = true
- free stalkers will join you as companions (will also charge for it in future)
Monster schemes
mob_walker scheme
Works the same way as the regular walker, except for a few differences:
path_walk flags:
- s=sound scheme
- (idle, eat, attack, attack_hit, take_damage, die, threaten, steal, panic, growling)
- с
- crouch from then on
- r
- run
- sig=signal_name
- set the given signal for xr_logic
path_look flags:
- t=time
- time to wain in milliseconds while looking at a point
- a=anim_set
- animation (stand_idle, sit_idle, lie_idle, eat, sleep, rest, attack, look_around, turn)
In custom data set:
[walker]
- path_walk
- path_look
- no_reset = true/false
- (required) do not reset the action of the previous scheme (sound, for instance); false by default
- actor_friendly = true/false
- (required) the monster never attacks first, although if the monster is attacked by the player, this flags is disabled; false by default
- npc_friendly = true/false
- (required) the monster never attacks first, even if the player is hostile
- friendly = true/false
- (required) the monster does not attack the player or other monsters. If they act aggressive, remembers them as enemeies and remains friendly to all; false by default
File: \gamedata\scripts\mob_walker.script
You can also control the bloodsucker's invisibility:
[mob_walker] ...
- state = vis
or
- state = invis
Also, the flag b (behavior) can be used in a mod_walker's path with the same parameters:
wp00|b=vis wp00|b=invis
mob_eluder scheme
The monster moves along the patrol waypoints (without considering connections between points), keeping at a distance from the player, keeping its course, exiting the scheme upon getting too close to the player and returning back when the distance increases.
- path = ...
- works as path_walk
- Time_capture = ....
- (required) the time in seconds the monster spends in this scheme; 10 by default
- Time_release = ....
- (required) the time in seconds the monster spends in the all-purpose scheme; 10 by default
- Min_dist = ....
- (required) distance in meters under which the monster switches to the all-purpose scheme; 5 by default
- Max_dist = ....
- (required) distance in meters over which the monster switches to the eluder scheme; 10 by default
Note: unstable.
File: \gamedata\scripts\mob_eluder.script
mob_remark scheme
Remarking scheme, but for monsters, not stalkers.
- state
- a specific state for the given monster (invisibility for a bloodsucker)
- dialog_cond = {+info, =func, -info, !func}
- conditions for opening a dialog
- anim
- comma-separated list of monster's animations
- anim.head
- comma-separated list of head animations
- tip
- which symbol is highlighted when the cursor is over it
- snd
- which sound it emits
- time
- animation playback time, used only for debugging
File: \gamedata\scripts\mob_remark.script
The trader is made using this scheme.
mob_combat, mob_death schemes
Works exactly the same way as the corresponding schemes for stalkers.
Files: \gamedata\scripts\mob_combat.script, \gamedata\scripts\mob_death.script
mob_jump scheme
Схема mob_jump. Теперь mob_jump служит для задания прыжков монстров без каких либо проверок и ограничений (расстояние, углы и т.д.). Указывается позиция с помощью патрульного пути, смещение относительно этой позиции и физический фактор прыжка.
Example:
[logic] active = mob_jump [mob_jump] path_jump = path ph_jump_factor = 2.8 offset = 0,10,0 on_signal = jumped | nil
path_jump – путь, с помощью которого мы задаем 1 целевую точку прыжка (с нулевым индексом). Реальная точка учитывает позицию path_jump[0] + смещение, заданное с помощью offset. offset – смещение по осям x,y,z соответственно, с помощью которого задается реальная точка в пространстве (может не находится на аи-ноде). ph_jump_factor - влияет на время прыжка. Визуально с помощью него задается кривизна траектории полёта. Чем он больше, тем прыжок более острый, быстрый (меньше дуга). С помощью данной схемы можно делать: перепрыгивание со здания на здание, выпрыгивание из окна, перепрыгивание высоких ограждений и др. Дефолтное значение = 1,8
Примечание: Фактически mob_jump - это не состояние, а разовое действие. При переходе в него монстр разворачивается в сторону прыжка и прыгает, поднимая сигнал jumped. Т.е. "on_signal = jumped | имя_схемы_или_nil" – является обязательным параметром в схеме, чтобы знать куда переходить дальше. При выборе позиции используется первая точка патрульного пути (0-вой индекс)
Mob_camp
Механика:
- Сидит на позиции, смотрит в точку
- Можно задать несколько позиций и время смены позиции.
- Перемещается между позициями бегом
- При виде врага переходит под универсальную схему (комбат/паника и т.д)
- Задаются минимальная и максимальная дистанции от врага до текущей camp-позиции
- Если враг уходит далеко - монстр возвращается на позицию
Использование:
[logic] active = mob_camp [mob_camp] path_look = way_look path_home = way_home time_change_point = 30000 home_min_radius = 20 home_max_radius = 50
skip_transfer_enemy – если прописать в кастом дату, то монстр не будет принимать врага от друших монстров, если его увидит (для этого нужно всех монстров в разные group разнести)
Описание параметров:
- path_home - путь, состоящий из точек, в которых будет находиться монстр
path_look - путь, состоящий из точек, в которые будет смотреть монстр
- time_change_point - время изменения текущей camp-точки (по-умолчанию10000), мс
- home_min_radius - минимальный радиус от врага до camp-точки (по-умолчанию 30), м
- home_max_radius - максимальный радиус от врага до camp-точки (по-умолчанию 40), м
Особенности: Минимальный и максимальный радиус необходимы для игнорирования врага, если он убежал далеко и для возврата на текущую позицию. Учитывается дистанция от врага до текущей позиции. Если дистанция меньше home_min_radius - атакуем врага, пока враг не исчезнет или дистанция не будет больше home_max_radius. Две дистанции необходимы для того, чтобы избежать ситуации, когда игрок стоит на границе радиуса действия и входит/выходит в зону и монстр бегает то в свою camp-позицию, то на врага.
- Выбор текущей позиции производится случайным образом
- Индексы точек пути для path_home и path_look должны совпадать (т.е. монстр сидит во второй точке path_home и смотрит во вторую точку path_look)
Единственным необходимым параметром является path_look Если не установлен path_home, в качестве кемперской точки учитывается позиция и нода объекта на спауне.
Для того чтобы монстр смотрел в разные точки на кемпер-позиции, path_look может состоять из нескольких точек.
Обязательные требования: home_min_radius < home_max_radius Количество точек путей path_look и path_home должно быть равным P.S. Mob_Camp можно использовать как альтернативу к монстрам под рестрикторами
Mob_home
This scheme is another way to replace restrictors. I recommend to make all monster gulags with mob_home.
Example:
[mob_home] path_home = path1 home_min_radius = 10 home_max_radius = 30
- aggressive_home
- monsters run, not walk towards the designated path_home
Monsters keep the path_home points. They attack an enemy if the enemy is within the home_min radius, otherwise hide. This implies that home_min should be made such that there would be enough covers inside. In idle they typically also go to cover. Home_max should be made like the largest restrictor in the "nest" scheme.
Added the ability to set minimum and maximum radius for the mob_home scheme in flags of the first point (path_home). Flags minr and maxr have been added for this purpose. In case radii are set both in the section and in the flags, the radius is taken from the section. Is neither is set, the values 20 and 40 are used, respectively.
Mob_fake_death
Is necessary for scenes in which zombies rise around the player as he walks.
Usage:
[logic] active = mob_fake_death [mob_fake_death] on_actor_dist_le = 5 | nil
The zombie stands up when the scheme begins, falls down when it ends.
Monster overrides
- actor_friendly
- if true, the monster does not attack the player until attacked first
- npc_friendly
- if true, does not attach the player or other monsters until attacked first
- friendly
- if true, does not attack anyone until attacked first
- braindead
- if true, ignores all attacks
Monster sections:
[mob_death], [mob_hit]
spawner section
Эта секция, которая присутствует как у NPC, так и у монстров, спавнит их по определенному условию (выводит в онлайн). Для того, чтобы они появились в данной точке, им надо поставить в настройках в Level editor флажок no_move_in_offline и отключен can_switch_offline. Спавнер прописывается в кастом дату объекта перед секцией logic Работает spawner следующим образом:
[spawner] cond = {+info -info =func !func}
Примечание. Если условия спавна не будет выполняться, то объект не заспавниться, а если он заспавнился и условие перестает выполняться, то объект будет спавнером уведен в оффалйн.
Example:
[spawner] cond = {=is_day} ; (объект заспавниться днем и уйдет в оффлайн ночью)
После того, как объект заспавнился, его берет под управление скрипт Logic
Spawning day and night monsters
[spawner]
- cond = {=is_day}
- only spawn the monster at day; to make it night only, write !is_day
- check_distance = true
- check to see if the player is nearby
- min_distance = 100
- do not spawn if the player is closer than this (150 by default, but this is really too much)
logic script
NB: если хотите заспавнить у npc что-то из вещей из custom data, то описание того, как это делается находится в Общей части в настройке профилей персонажей (только тег supplies писать не надо!)
Скрипт logic управляет переключением схем. В customdata любого персонажа (кроме свободных) должна присутствовать секция [logic].
Функции, на которые ссылается секция [logic] должны находится в файлах \gamedata\scripts\xr_effects.script или \gamedata\scripts\xr_conditions.script.
В секции должно присутствовать одно из полей: active = активная схема, запускающаяся первой. cfg = имя_ltx_файла_с_настройками
Если задано поле cfg, то в качестве настроек персонажа будет использовано содержимое указанного файла. Пример. Settings: простого walker-а:
[logic] active = walker
[walker] path_walk = walk1 path_look = look1
Переключение схем выполняется с помощью дополнительных условий схемы logic, которые прописываются в секции текущей активной схемы. Существуют следующие условия переключения: Список доступных схем перечислен в главе схемы. Примечание: если logic переключает между несколькими одноименными схемами (например несколькими walker), то их можно нумеровать (walker1, walker2) или через @ давать более информативные названия walker@day, walker@alarm и т.д.
on_actor_dist_le = number | scheme - дистанция до игрока <= number on_actor_dist_le_nvis = number | scheme - дистанция до игрока <= number без проверки на видимость on_actor_dist_ge = number | scheme - если дистанция до игрока > number on_actor_dist_ge_nvis = number | scheme - если дистанция до игрока > number без проверки на видимость on_signal = signal | scheme - срабатывает по приходу сигнала signal от текущей активной схемы on_info = scheme - срабатывает всегда on_timer = msec | scheme - срабатывает через msec мс после включения схемы on_game_timer = sec| scheme – срабатывает через sec секунд игрового времени, после включения схемы on_actor_in_zone = restrictor_name | scheme – если актер в зоне, (указывается имя рестриктора) on_actor_not_in_zone = restrictor_name | scheme – если актер не в зоне, (указывается имя рестриктора) on_npc_in_zone = npc_story_id | restrictor_name | scheme – если NPC в зоне, указывается story_id NPC, и имя рестриктора on_npc_not_in_zone = npc_story_id | restrictor_name | scheme - если NPC не в зоне, указывается story_id NPC, и имя рестриктора on_actor_inside = scheme - зона проверяет, находится ли игрок внутри нее on_actor_outside = scheme - зона проверяет, находится ли игрок за ее пределами
NB: с любыми из вышеперечисленных параметров можно работать следующим образом: on_info = {....} %...% on_info2 = {....} %...% on_info3 = {...} %...% и так далее до посинения
а также условия для переключения на описанные выше секции. combat_ignore_cond = on_hit = on_death = on_combat = on_use =
Logic script syntax
Example: для того, чтобы персонаж ходил по пути walk1, а при приближении игрока на дистанцию 5 метров, переключался на путь walk2 (но только при условии, что он видит игрока), нужно написать следующее:
[logic] active = walker1 [walker1] path_walk = walk1 path_look = look1 on_actor_dist_le = 5 | walker2 [walker2] path_walk = walk2 path_look = look2
Выше рассмотрено безусловное переключение секций. Перед именем секции в фигурных скобках {} можно задавать дополнительные условия, а после имени секции - так называемые "эффекты", которые заключить в знаки процента: %%. Эффекты будут применены только в случае активации секции. Можно не задавать имя секции, а задать только условия и/или эффекты. Тогда активной останется старая секция, но условия и эффекты будут все равно обработаны. Если все условия в фигурных скобках не выполняются, секция активирована не будет.
Example:
on_actor_dist_le = 5 | {условие} walker2 %эффекты%
Условия могут быть следующими:
- +infoportion - требуется присутствие infoportion у actor
- -infoportion - требуется отсутствие infoportion у actor
- =func - требуется, чтобы func вернула true
- !func - требуется, чтобы func вернулся false
Эффекты могут быть следующими:
- +infoportion - в случае включения секции у actor будет установлен infoportion
- -infoportion - в случае включения секции у actor будет убран infoportion
- =func - в случае включения секции стартует функция func
Несколько условия или эффектов разделяются проблемами:
on_actor_dist_le = 5 | {+info1 -info2 +info3} walker2 %+info4 =func%
Можно задавать сразу несколько секций, разделенных запятыми. Порядок обхода при этом - слева направо. После срабатывания первого из условий, обход прекращается. В примере ниже, если установлен info1, будет включена схема walker2, иначе, если установлен info2, будет включена схема walker3, иначе будет включен walker4:
on_actor_dist_le = 5 | {+info1} walker2, {+info2} walker3, walker4
В описанном выше поле active секции logic, можно также задавать условия, например:
[logic] active = {=actor_friend} walker@friendly, walker@enemy
В логических условиях теперь принимается ключевое слово never, которое означает, что условие ложно. For example: combat_ignore_cond = {=actor_enemy =actor_has_suit} always, {=actor_enemy} never %...эффекты...%
Вышеприведенная конструкция включает игнорирование боя, если у NPC враг - игрок в костюме, но отключит его, если врагом является игрок, но без костюма, при этом сработают эффекты (%%) секции never. Таким образом, выбор секции never равносилен отсутствию секции (несрабатыванию условия), но эффекты в знаках процента при этом срабатывают.
Пример работы с секцией nil. Секция nil выводит из-под скриптовых схем персонажа, монстра или объект и отпускает его под управление движка. Это надо если какое-либо условие выполнившись 1 раз больше не нуждается в проверке, при этом экономятся ресурсы машины, которые на каждом апдейте проверяют это условие.
[logic] active = sr_idle [sr_idle] on_actor_inside = nil %+esc_actor_inside%
То есть, при входе актера в рестриктор выдается инфопоршн и рестриктор уходит в секцию nil, больше не проверяя наличие игрока. NB: Обратно из секции nil под скрипты объект вернуть уже невозможно! Учитывайте это, используя ее.
An example of fairly complex logic
[logic] active = walker combat_ignore = combat_ignore on_hit = hit on_death = death [hit] on_info = %+alert% [death] on_info = %+alert +trup3% [walker] path_walk = walk_svoboda3 path_look = look_svoboda3 combat_ignore_cond = {-alert} on_timer = 25000 | remark [remark] anim = idle snd = stalker_talk_kampfire no_move = true no_rotate = true on_hit = hit on_death = death combat_ignore_cond = {-alert} [combat_ignore]
Lets look at this step by step. At first, the stalker works according to the walker scheme. While at it, he ignores combat until the alert infoportion is set. Then he waits 25 seconds and switches to the remark scheme. In remark he plays an idle animation, chats on specified subjects, does not turn, does not move, still ignores combat. If he is hit or killed (on_death), he will get an alert infoportion and stops ignoring combat (obviously, if he is a corpse, that won't help, but there are three of them on the scene, and then the rest will spring into action). If he is killed, he will also get a trup3 infoportion, which will announce that this stalker is dead.
Now, here is his opponent's logic:
[logic] active = walker combat_ignore = combat_ignore [walker] path_walk = soldier_walk1 path_look = soldier_look1 combat_ignore_cond = always team = assault_group on_signal = assault | camper [camper] path_walk = soldier_walk1_2 path_look = soldier_look1_2 radius = 5 on_info = {+trup1 +trup2 +trup3} walker2 [walker2] path_walk = soldier_walk1_3 path_look = soldier_look1_3 [combat_ignore]
He is in the walker scheme, ignores combat (in any situation, by the way). He is part of the assault_group. When he comes to the endpoint of his route (where he is synchronized with the rest of the group, as is specified in the paths) he gets the assault signal and switches to the camper scheme. In this scheme he does not have combat_ignore specified and, therefore, starts shooting at the enemy. After all three oppponents are dead, with them setting infoportions trup1, trup, and trup3 upon dying, he switches to walker2 (goes to the campfire).
space_restrictor logic scheme
Общее замечание: Чтобы исключить ситуацию, когда актёр проскакивает через рестриктор и тот не успевает сработать, старайтесь ставить рестриктор так, чтоб минимальная ширина была больше 2 метров.
[sr_idle] scheme
The purpose of this scheme is to switch to another scheme when one of the standard logic conditions is met. It does not do anything on its own. Example of a restrictor's settings:
[logic] active = sr_idle [sr_idle] on_actor_inside = nil %+esc_actor_inside%
Note that when the check goes off, the active scheme switches to nil, so that it does not continue the useless check on each update. You do not have to set nil. Often this scheme works together with a spawner. The restrictor gives out an infoportion upon entry into the zone, and the spawner uses it to spawn something.
File \gamedata\scripts\sr_idle.script
[sr_no_weapon] scheme
This scheme removes the player's weapon uponn entry into its zone. Example of a restrictor's settings:
[logic] active = sr_no_weapon
[sr_no_weapon]
File \gamedata\scripts\sr_no_weapon.script
[sr_sound] scheme
- snd
- comma-separated list of all sound names
- type
- comma separated list of sound types. For convenience, sound sets were introduced. For instance, to avoid listing the full set of wood floor sound types, you can specify floor_wooden.
- delay
- delay before playing the sounds in seconds of real time; 0 by default
- idle
- duration of time to ignore entry into the zone after the last sound begins. For instance, to make sure howling is no more frequent than once every few minutes. In seconds of real time. 0 by default.
- rnd
- percent probability of playing the sound; 100 by default
- position
- name of the path the points of which to play the sound at. Could be random, meaning a random place in the radius of 15-50 meters of the player. If this parameter is not set, then the player's position is assumed.
- slide_velocity
- speed of movement of the sound along the path; 3 by default
- slide_sound_once = true\false
- true - play the sound once, even if it does not reach the last point
- false – if the sound has ended, but not reached the last point, play it again
- false by default
- play_at_actor = true/false
- forces the sound play continuosly at actor's location. If this is true and the path is set (or is random) the game will crash.
This scheme is meant to be used to play sounds at the actor's entrance in a restrictor.
Supports sound_end.
You must set either snd or type. You can set both. The list of sounds is created based on these parameters. When the actor enters a restrictor, a random sound from this list is played.
Example:
[logic] active = sr_sound [sr_sound] type = floor_wooden snd = ambient\wind1, ambient\sparks1 rnd = 50 position = random idle = 120 delay = 3
You can make a "sliding" sound. You need a patrol path. The sound will start playing at the beginning of the path and move from one point to another (in the order they are set in the path) with the speed slid_velocity.
[logic] active = sr_sound [sr_sound] type = random position = way slide_velocity = 8 slide_sound_once = true
File \gamedata\scripts\sr_sound.script
[sr_tip] scheme
The purpose of this scheme is to give the player a tip on entry into a restrictor.
- name
- news name
- type
- news to send as global news, tips to send with the sender's name; news by default
- sender
- if type is tips then this is the string identifier of the sender character's icon; the dealer's icon by default
- cond
- condition for firing; set to entry into the restrictor by default
- single = true/false
- whether the tip should only be given once; false by default
Example:
[logic] active = sr_tip [sr_tip] name = tips_esc_trader_about_pda type = tips cond = {+infoportion1 –infoportion2 } showtime = msec ; time in seconds the tip will be displayed for; does not work properly
If it should be played only once, and this happens often, you can add the following line:
on_actor_inside = nil
File \gamedata\scripts\sr_tip.script
Sr_light
Зона, в которой фонарики у неписей будут включены независимо от времени суток.
Работает следующим образом:
[logic] active = sr_light [sr_light] light_on = true/false (свет включен/выключен)
Также работает вместе с кондлистом:
[logic] active = sr_light [sr_light] light_on = true/false (свет включен/выключен) on_info = {+info1} section %+info2%
Sr_territory
Занимается эта схема тем, что отлавливает всякие события, происходящие внутри рестриктора. Пока что она отлавливает только хиты и смерть сталкеров. Пример использования примерно следующий:
[logic] active = sr_territory@outside [sr_territory@outside] on_actor_inside = sr_territory@inside [sr_territory@inside] on_actor_outside = sr_territory@outside territory_hit = {-bar_dolg_territory_1_hit} %+bar_dolg_territory_1_hit%, {-bar_dolg_territory_2_hit} %+bar_dolg_territory_2_hit%, {-bar_dolg_territory_3_hit} %+bar_dolg_territory_3_hit% territory_death = {-bar_dolg_territory_kill} %+bar_dolg_territory_kill%
То есть здесь видно, что когда игрок находится внутри рестриктора, то считается количество нанесенных хитов, а также учитывается был ли кто-то убит или нет. Поскольку схема работает только с игроком – то хиты и смерть засчитываются только от игрока.
Sr_mapspot
При входе в рестриктор он сам себя подсвечивает на карте.
Параметры:
- hint - id подсказки в string table (обязательный параметр)
- location - название типа подсветки (не обязательный параметр, по умолчанию "crlc_small")
Example:
[logic] active = sr_mapspot [sr_mapspot] hint = “gar_swamp” location = crcl_big
Sr_particle
Данная система отыгрывает партиклы как статичные так и движущиеся в указанном месте и в указанное время. Работет она следующим образом:
-
для партикловой системы с путем камеры:
[sr_particle] name = explosions\campfire_03 ; имя партикловой системы path = particle_test.anm ; имя пути камеры mode = 1 ; (обязательно !!!) looped = true/false ; флаг зацикленности партиклов
(обязательно с расширением ANM !!!) Здесь партиклы будут молча перемещаться по пути.
-
для партикловой системы с обычным патрульным путем:
[sr_particle] name = explosions\campfire_03 ; имя партикловой системы path = part_points ; имя патрульного пути mode = 2 ; (обязательно !!!) looped = true/false ; флаг зацикленности партиклов
В вейпоинтах можно задавать флаг s=имя_звуковой_темы и d=число время задержки перед проигрыванием (задается в миллисекундах. Если не задано, то 0). s - имя звуковой темы в sound_themes.ph_snd_themes из которой будет случайно выбран звук для проигрывания во время проигрывания партикла. Звук не зацикливается и играет только один раз.. Результат = партиклы отыгрываются во всех вейпоинтах одновременно (или с задержкой см. выше).
При looped=true по окончании проигрывания партиклов, они будут запускаться сначала, но уже без задержек. Сигнал particle_end выдаваться не будет. При looped=false сигнал будет выдан, когда все источники партиклов отыграют. Поддерживается кондлист. Если рестриктор переходит в другую секцию, то автоматически перестают отыгрываться партиклы и замолкают звуки при них. Этот рестриктор является объектом, отслеживающим партиклы и нет никакой необходимости чтобы игрок в него заходил.
Sr_sound_act
Итого, схема, которая играет саунд в голове актера. Всякие там переговоры по ПДА и прочие фейки
[sr_sound_act] snd = ambient\random\new_drone1 ; имя звукового файла *delay = 2000 ; задержка перед проигрыванием *delay_max = 4000 ; между проигрыванием звука будет взят случайный промежуток между delay и delay_max. *on_signal = sound_end | nil ; по сигналу можно перейти в другую секцию. theme = < ; имя темы из ph_sound_themes>
- stereo = true/false (по умолчанию false). При установке этого параметра к файлу, который задан параметром snd или в звуковой теме будут добавляться (автоматически) суффиксы _r и _l для загрузки левого и правого каналов и, соответственно, вся эта фигня будет играться.
Если указывается тема, то звук будет играть зациклено, случайным образом выбирая один из звуков прописанных в теме, если указывается звук, то он отыгрывается один раз. Схема поддерживает кондлист.
Sr_timer
Example of use:
[logic] active = sr_timer@1 [sr_timer@1] type = dec start_value = 10000 on_value = 0 | sr_timer@2 [sr_timer@2] type = inc on_value = 15000 | nil %+info1%
Fields:
- type
- counter type: inc or dec; inc by default
- start_value
- starting value in REAL milliseconds. For decrementing counters, settings this is required. For incrementing it is 0 by default.
Switches from section sr_timer can be caused by regular conditons (on_timer, on_info) or by the special condition on_value. In general, on_value should be used for performing some actions based on the counter's state. For example:
on_value = 5000| %+info1% | 1000| %+info2%
Sr_psy_antenna
Зоны с такой секцией позволяют управлять эффектами от пси-воздействия (на Янтаре и Радаре). Сейчас можно управлять интенсивностью излучения и интенсивностью получения повреждений.
Способ применения: Расставить зоны, в каждой зоне написать, сколько процентов к интенсивности излучения и повреждения она добавляет/отнимает. Зоны могут быть вложены друг в друга, пересекать друг друга.
- eff_intensity = - увеличение/уменьшение в % от базового значения интенсивности излучения.
- hit_ intensity = - увеличение/уменьшение в % от базового значения наносимого повреждения.
Пример зоны, которая добавляет 70% излучения:
[logic] active = sr_psy_antenna [sr_psy_antenna] =_intensity = 70 hit_ intensity = 70
Пример зоны, которая убирает 30% излучения:
[logic] active = sr_psy_antenna [sr_psy_antenna] intensity = -30
Sr_teleport
Собственно, телепорт. Настраиваются следующим образом:
[logic] active = sr_teleport [sr_teleport] timeout = 0 point1 = point1 look1 = look1 prob1 = 10 point2 = point2 look2 = look2 prob2 = 20
где: timeout - задержка в срабатывании телепорта в миллисекундах. point - одноточечный патрульный путь куда переместить look - одноточечный патрульный путь куда повернуть.
Далее идут настройки точек назначения с удельными весами. То есть в перечисленном выше примере вероятность телепортнутся во вторую точку в два раза выше, чем в первую. Максимальное количество точек назначения - 10. Телепорты необходимо ставить совместно с особой аномальной зоной, которую сейчас делает Проф. Зона добавит визуализацию и создаст эффект втягивания.
Sr_sleep and sleep configuration
Появилась возможность задавать зоны сна.
[sr_sleep]
- cond = <condlist>
- type = nightmare/normal/happy/all - Задает тип сна разрешенный в данной зоне (по умолчанию all). Влияет (группирует) только на несценарные сны.
- dream_prob = <число от 0 до 100> - вероятность просмотра несценарных сновидений в данной зоне (по умолчанию 80). В противном случае будет только черный экран.
Необязательное поле cond задает условие(я), при котором в этой зоне можно спать. Сейчас производится индикация зон, где разрешен сон. В левом нижнем углу отображается маленькая иконка легких при входе в такую зону. Вероятно, позже будет изменена на другую. Сновидения теперь делятся на сценарные и обычные. Сценарные сновидения отыгрываются один раз при выполнении необходимых условий. Обычные сновидения проигрываются, если нет сценарных или ни одно условие выполнения сценарных не сработало. Можно задавать вероятность отыгрывания обычных сновидений в целом, а также задавать вероятность срабатывания каждого конкретного сновидения в отдельности. Обычным сновидениям можно задавать тип и потом ограничивать по нему сны воспроизводимые в sr_sleep.
В файле misc\dream.ltx задаются настройки снов.
Секция videos. Полями задаются пути к видеофайлам со снами.
Секция dreams. Поля: regular_probability = <число от 0 до 100> - вероятность проигрывания обычных сновидений в целом regular - список секций с настройками для обычных сновидений scene - список секций с настройками для сценарных сновидений
Settings: обычных сновидений: dream - имя поля из секции videos probability = <число больше 0> - чем больше, тем больше вероятность проигрывания сна. type = nightmare/normal/happy - тип сна.
Settings: сценарных сновидений: dream - имя поля из секции videos cond = <condlist> - условия срабатывания to_regular = <вероятность,тип> - необязательное поле. Дает возможность переводить сценарный сон после первого отыгрыша в разряд обычных. <вероятность, тип> аналогичны probability и type из настроек обычных сновидений соответственно.
Sr_cutscene
Эта схема предназначена для проведения анимации камеры c некоторым эффектом (pp_effector). Последовательность действий, осуществляемых схемой, состоит из мгновенного перемещения игрока в начало пути point и ориентации его взгляда на начало пути look, потери управления игроком и начала анимации камеры cam_effector по завершении которой игрок вновь получает управление.
[sr_cutscene] point = <имя пути> - путь в первую точку которого переносится игрок look = <имя пути> - путь в первую точку которого смотрит игрок
- pp_effector = <имя файла с эффектом> - файл, расположенный в папке
gamedata\anims\ и содержащий эффект (имя файла пишется без расширения) cam_effector = <имя файла с анимацией камеры> - файл, расположенный в папке gamedata\anims\camera_effects\ и содержащий анимацию камеры (имя файла пишется без расширения)
Various settings for objects
[ph_idle]
A section for all physical objects. Supports a condlist. Could be used to transfer objects into when needed.
Doors, [ph_door] section
All folding doors work the same way.
- locked = false\true
- false by default
- Closed = false\true
- true by default
- tip_open = (if locked == false, then tip_door_open, else tip_door_locked)
- the tip that shows up when the door is targeted if the door is closed
- tip_close = (if locked == false, then tip_door_close, else empty value)
- the tip that shows up when the door is targeted if the door is open
- snd_init
- the sound that will be played when the scheme is initiated
- snd_open_start
- the sound that will be played on attempts to open the door
- snd_close_start
- the sound that will be played on attempts to close the door
- snd_close_stop
- the sound that will be played when the door is closed shut
Example:
If you need to make a door that will open with a click on some event, then you can use the snd_init field and switching schemes. In this example, when the ph_door@unlocked is iniated, the snd_init sound is played, that is, trader_door_unlock:
[logic] active = ph_door@locked [ph_door@locked] locked = true snd_open_start = trader_door_locked on_info = {+esc_trader_can_leave} ph_door@unlocked [ph_door@unlocked] locked = false snd_init = trader_door_unlock snd_open_start = trader_door_open_start snd_close_start = trader_door_close_start snd_close_stop = trader_door_close_stop
File \gamedata\scripts\ph_door.script
Buttons, [ph_button] section
When you press a button, this switches sections and gives out an infoportion.
[logic] active = ph_button@locked [ph_button@locked] anim_blend = false anim = button_false on_press = ph_button@unlocked %+cit_jail_door_opened%
- on_press
- what happens when the button is pressed
- anim
- animation to play when the button is pressed
- anim_blend
- smooth animation
File \Gamedata\scripts\ph_button.script
- tooltip
- is there to show a textual hint when the button is targeted. The hint is needed to at least explain that it can be presseed.
Example:
[logic] active = ph_button@active [ph_button@active] anim = lab_switcher_idle tooltip = tips_labx16switcher_press on_press = ph_button@deactivated %+terrain_test% [ph_button@deactivated] anim = lab_switcher_off
To make sure the message stays valid with different keyboard settings, you should use tokens. For example:
<string id="tips_labx16switcher_press"> <text>To disable this magical contraption press ($$ACTION_USE$$)</text> </string>
Here is an example of a button that does not work each time, but only if a certain condition is met:
[logic] active = ph_button@locked [ph_button@locked] anim = button_false ; an animation for disabled buttons on_info = {+val_prisoner_door_unlocked} ph_button@unlocked on_press = ph_button@unlocked %+val_prisoner_door_unlocked% [ph_button@unlocked] anim = button_true on_info = {-val_prisoner_door_unlocked} ph_button@locked on_press = ph_button@locked %-val_prisoner_door_unlocked%
Projector
В точках look пути, в которые смотрит прожекторщик, нужно прописать sl=имя_прожектора
Например wp00|sl=esc_sl1
Тогда при повороте в эту точку персонаж повернет в нее и прожектор.
Combination locks
При введении указанного кода выдает инфопоршн
[logic] active = ph_code@lock
[ph_code@lock] code = 1243 on_code = %+infoportion%
File: \gamedata\scripts\ph_code.script
Ph_gate:
То же самое, что и ph_door, но для ворот, состоящих из двух дверей: Вместо параметров closed и locked сейчас используются параметры: state: состояние, в котором дверь находится при инициализации (по умолчанию none)
- open - в открытом
- closed - в закрытом
none - в текущем (дефолтном или оставшемся от предыдущей схемы)
locking: блокировка дверей (по умолчанию none) stick - прилипание дверей к крайним состояниям (пока в процессе настройки)
soft - дверь заблокирована с помощью силы, т.е. можно ее открыть/пробить машиной Состояния в этом положении:
- open - блокировать в открытом состоянии
- closed - в закрытом
none - не используется (мягкая блокировка возможна только в крайних положениях)
hard - блокировка двери с помощью границ. Ворота можно только сломать Состояния в этом положении:
- open - блокировать в открытом состоянии
- closed - в закрытом
- none - в текущем
none - дверь не заблокирована
Общие параметры: left_limit, right_limit - задают угол [0-180] открытия каждой из створок ворот. По умолчанию - 100 градусов. breakable - (true/false) определяет можно ли сломать ворота. По умолчанию true.
Звуковые параметры аналогичны ph_door
Examples:
[ph_gate@locked] ;блокировка в открытом состоянии, неразбиваемые. state = opened locking = soft left_limit = 130 rigt_limit = 60 breakable = false [ph_gate@opened] state = opened locking = stick [ph_gate@closed] state = closeded
File: \gamedata\scripts\ph_gate.script
Ph_sound
Прописывается у физического объекта какие звуки он выдает (изначально планировался как матюгальник).
[ph_sound] snd = имя темы из файла sound_theme.script из таблицы ph_snd_themes
- looped = true/false зацикленое воспроизведение звука (default - false)
- min_idle = минимальное время простоя перед включением звука (мс)
- max_idle = максимальное время простоя перед включением звука (мс)
- random = true/false (def - false). Если = true, то из темы будет выбран рандомный звук и таким образом звуки будут играться до посинения
NB! Если мы задаем random = true и looped = true, то версия сыпется
Также поддерждивается кондлист. Данная схема работает через задницу, поэтому зацикленный звук будет продолжать отыгрываться, даже если объект уходит в nil. В связи с этим надо создавать новую секцию, которая бы отыгрывала одиночный короткий звук, после которого (поскольку он будет точно также играться раз за разом) ставим on_signal = sound_end| nil
An example of such twisted logic:
[logic] active = ph_sound [ph_sound] snd = gar_seryi_shooting looped = true max_idle = 5000 on_actor_in_zone = gar_seryi_factory| ph_sound@end [ph_sound@end] snd = gar_seryi_shooting_2 looped = false on_signal = sound_end| nil
Кроме того специфическим образом создается звуковая схема. В sound_theme.script в начале файла есть секция ph_themes в которой и описываются темы для физ объектов. For example: ph_snd_themes["gar_seryi_shooting"] = {characters_voice\human_01\scenario\garbage\distance_shooting}
Кроме того (незадекларированная фича) ph_sound можно вешать на рестрикторы. Но за правильность работы в таком случае никто ответственности не несет.
File: \gamedata\scripts\ph_sound.script
Ph_force
This scheme allows one to kick an object in a given direction. Is written in custom data of an object.
- force
- force applied to the object, measured in dead badgers
- time
- durationi of time the force is applied to the object, measured in seconds
- delay
- delay in seconds before the force is applied
- point
- name of a patrol path that is to be used as the target (where the object will point)
- point_index
- index of a point of the patrol path towards which the object will fly
Ph_on_death
Scheme for tracking destruction of physical objects and producing various effects.
Example:
[logic] active = ph_on_death [ph_on_death] on_info = %effects%
To be used only with destructable physical objects.
Ph_car
Settings to let the player control a car.
[ph_car]
- usable = condtion list
- list of conditions returning true (by default) or false
Example:
[logic] active = ph_car [ph_car] usable = {+val_actor_has_car_key}
Based on this scheme, you can make a car that will start only if the actor has a key for it.
Ph_heavy
Прописывается в физ объектах, которые запрещены для швыряния бюрерам и полтергейстам. Например, если они должны лежать на конкретном месте (типа документов сюжетных) или слишком громоздки по габаритам, чтобы их можно было красиво кидать. В кастом дате пишем:
[ph_heavy]
Ph_oscillate
Схема предназначена для плавного раскачивания физики (лампы, висящие зомби и т.д.) Logic example:
[ph_oscillate] joint = provod ; имя кости к которой будет применена сила force = 5 ; собственно сила (в ньютонах) period = 1000 ; время прикладывания силы.
Сила прикладывается к кости объекта с линейным наростанием. То есть в течении заданого периода времени сила вырастет с 0 до заявленого значения. После этого настает пауза (сила не применяется) на время period/2. После окончания паузы сила применяется так же, как и в начале, но в обратном направлении.
Smart terrains and gulags
Smart terrain
By a smart terrain we mean a zone that, upon entry, captures a stalker in a gulag and makes him do work for this gulag. After a period of time he escapes the gulag and walks free.
How to set a smart terrain? For every smart terrain you have to:
- Set a smart terrain with the required shape. It is not recommended to make them large, since size affects performance.
- Specify the settings in its custom data.
- Set paths for the corresponding behavior schemes.
Custom data parameters:
[gulag1]
- type
- capacity
- max number of people
- offline
- if the gulag can go offline; false by default
- squad
- the squad to set for all stalkers in the gulag (level #)
- groups
- comma-separated list of groups
- stay
- duration of time the NPC remains under the smart terrain; permanently by default
- idle = min, max
- duration of time the smart terrain remains active after the last NPC leaves
- cond
- list of conditions necessary to create a gulag
- {+info -info = func !func} - if the condition is not met, the gulag is disbanded and all its inmates begin to be controlled by logic specified in their custom_data
Gulag type should not be quoted. If either squad or groups is not set, then the corresponding properties of stalkers will not change. All time is set in hours of game time and can be fractional
Path names should always start with the name of the given smart terrain. For instance: esc_smart_ambush_vagon_sleep.
If paths for a smart terrain are for several people (campers, walkers), then their names should always end with a number (esc_smart_ambush_vagon_walk1, esc_smart_ambush_vagon_walk2).
There can be several gulags under a single smart terrain. They can be set in several sections [gulag2], [gulag3], etc. After a stalker enters the smart terrain, one of the available gulags will be chosen at random.
Standard smart terrain types
If you want to prevent a stalker from being captured, add the following line to his custom data:
[smart_terrains] none = true
If the stalker is already under some smart terrain's control, he will ignore the others.
campers
Custom data:
[gulag1] type = campers capacity = от 1 до 3
Paths:
- camper_walk1, camper_look1
- camper_walk2, camper_look2
- camper_walk3, camper_look3
walkers
Could be used to conduct searches, and lots of other stuff.
Custom data:
[gulag1] type = walkers capacity = от 1 до 3
Paths:
- walker_walk1, walker_look1
- walker_walk2, walker_look2
- walker_walk3, walker_look3
search
Custom data:
[gulag1] type = search capacity = 1
Paths:
- search_walk, search_look
Works like this:
- The character walks through waypoints, looks about.
- Stops at certain points, searches (caution, search, hide)
- Utters some phrases while at that
rest
A stalker switches between sleeper, walker, and rest (eats, drinks vodka).
Custom data:
[gulag1] type = rest capacity = 1
Paths:
- rest – two-vertex path (possibly one). He sits in one, looks towards the other.
- sleep - two-vertex path (possibly one). He sleeps in one, looks towards the other.
- rest_walk, rest_look
Gulags
A gulag is a means of joining several stalkers under centralized control. Main features:
- A gulag has a task list. A task is a set behavioral scheme, or a chain of schemes.
- Tasks have priorities.
- A gulag assigns entering stalkers to jobs with highest priority first.
- Gulags have states. Each condition corresponds to a unique set of tasks, different from the set of any other condition.
A gulag is created like this:
1. First, a list of states for the gulag has to be determined: day, night, calm, active, etc. Simple gulags might have only one state, a complex one should have many. This introduces more variety and looks better.
2. Determine the maximum number of people that can be controlled by the gulag. That is, determine the gulag's capacity. It should be such that in any state the gulag should be able to find a task for every person.
3. For every state the gulag should have a list of tasks. These tasks can be active (centry, patrol, etc) or passive (sitting at a campfire, sleep). Each job has its own priority. Correspondingly, passive tasks should have lower priority.
4. Use the editor to set the number of people to be in the gulag and cover it with a smart terrain (it is an error to use space_restictor). The terrain should be given a meaningful name. This name will also serve as a prefix for all patrol paths for this gulag. For instance, if you call the terrain esc_blockpost, then all patrol paths should start with this prefix, as esc_blockpost_guard_walk, for instance. Custom data for the zone should contain settings for the gulag.
[gulag1]
- type
- capacity
- maximum number of people
- offline = true/false
- whether the gulag can go offline
- squad = squad
- the squad stalkers under the gulag are assigned to
- groups
- comma-delimeted list of groups
- stay
- duration of time the NPC remains under the smart terrain; permanently by default
- idle = min, max
- duration of time the smart terrain remains active after the last NPC leaves
- cond
- list of conditions necessary to create a gulag
- {+info -info = func !func} - if the condition is not met, the gulag is disbanded and all its inmates begin to be controlled by logic specified in their custom_data
- respawn
- respawn name (calls the respawner with the given name every time someone from the smart terrain starts working on a task)
Capacity should always be set. It should be less than or equal to the number of tasks.
Gulag type should be unquoted.
The offline field could be used to prevent the gulag from going offline. That is, it can exist in offline mode, but cannot go into it.
Gulag type should not be quoted. If either squad or groups is not set, then the corresponding properties of stalkers will not change. All time is set in hours of game time and can be fractional
5. In script \gamedata\scripts\gulag_<level name>.script you should set the condition under which stalkers are captured by the gulag. The function checkNPC should be appended with the condition:
if gulag_type == "gar_dolg" then return npc_community == "dolg" end
This function takes two parameters: gulag type and character's community. In this case, the the gulag with type gar_dold will accept all characters in faction Dolg.
6. In file \gamedata\scripts\gulag_<level name>.script you should desribe how gulag states should switch.
function loadStates(gname, type)
Takes the name of a zone and gulag type. The gulag's state is described as a function returning gulag state number. For example:
if type == "gar_maniac" then return function(gulag) if level.get_time_hours() >= 7 and level.get_time_hours() <= 22 then return 0 -- день else return 1 -- ночь end end end
In this case, if it is between 07 and 22 hours, the gulag is in daytime mode, otherwise in nighttime mode.
8. In file \gamedata\scripts\gulag_<level name>.script you should describe a gulag's tasks. The function loadJob loads all the allowed tasks. The function itself takes the following parameters:
function loadJob(sj, gname, type, squad, groups)
- sj
- the gulag task table itself
- gname
- smart terrain name; used as a prefix
- yype – тип гулага
- squad, groups
- squad and grouip table, if we need to override the native stalker groups with some other ones. For each task you should set a squad and a group to assign a stalker to upon recieving a task.
Approximate description of gulag tasks:
The following gulag describes behavior of a single person, but there is usually many more. The given person in zero state (daytime) performs one task, in first state (nighttime) another task.
--' Garbage maniac if type == "gar_maniac" then t = { section = "logic@gar_maniac_camper", idle = 0, prior = 5, state = {0}, squad = squad, groups = groups[1], in_rest = "", out_rest = "", info_rest = "" } table.insert(sj, t) t = { section = "logic@gar_maniac_sleeper", idle = 0, prior = 5, state = {1}, squad = squad, groups = groups[1], in_rest = "", out_rest = "", info_rest = "" } table.insert(sj, t) end
Field descriptions:
- Idle
- pause between repeated execution of the same tasks. There is no pause in this case. Pause is usually set for patrols.
- Prior
- task priority. At first stalkers occupy the higher priority tasks. The higher the number, the higher the priority.
- In_rest, out_rest
- restrictors set for the character for this task
- Section
- section in \gamedata\config\misc\gulag_<level name>.ltx, in which the real behavior scheme corresponding to this task is set.
- the stalker's group will be chosen from the group array set in custom data. The array is indexed starting with 1.
- Info_rest
- sets the name of the restrictor, inside of which the person performing the task is guarded from all dangers
The task description may also contain additional conditions for when the stalker can recieve the task. For example:
predicate = function(obj) return obj:profile_name() == "soldier_commander" end
That is, the given task can only be carried out by a person with the soldier_commander profile.
9. В \gamedata\config\misc\gulag_<level name>.ltx you should specify which behavior schemes correspond to each task. FOr instance, for the aforementioned gar_maniac:
;---------------------------- ;-- GARBAGE MANIAC ;---------------------------- [logic@gar_maniac_camper] active = camper@gar_maniac_camper [camper@gar_maniac_camper] path_walk = walk1 path_look = look1 [logic@gar_maniac_sleeper] active = sleeper@gar_maniac_sleeper [sleeper@gar_maniac_sleeper] path_main = sleep wakeable = true
Here settings correspond to regular stalker custom data, with the followin differene:
- paths should be specified without a prefix. THat is, if the zone was called gar_maniac, a path on the level might be called gar_maniac_walk1, but gamedata\config\misc\gulag_<level name>.ltx should be specified as simply walk1.
- section names should be appended with @ and the gulag name and, possibly, additional information (such as walker2@rad_antena_gate)
- for each taask, logic section names should be appended @ and the gulag name, additional data, and active behavior scheme for (such as logic@rad_antena_gate_walker2
There is no leader field for gulag tasks. There is the dependent field. A task can only be taken if the dependent task is taken first. For instance, follower can be set only after someone is set to work as the leader (leader's name is now in the dependent field). Correspondingly, the task priority for tasks on which others dpeend should be greater than theirs.
New smart terrain capabilities
Возможности нового смарттеррейна (СТ):
- Не держит сталкеров постоянно в онлайне. Работает стандартный онлайн-радиус.
- Сталкеры идут на ближайшие работы.
- На места работ сталкеры идут независимо от того, в онлайне они или в оффлайне.
- СТ в офлайне работает так же, как и в онлайне: выполняет переключение своих состояний, перераспределение работ.
- Сталкерам можно прописать, при каких условиях в какие СТ они могут идти. (см. ниже) Если сталкер попал в СТ, то онбудет находится в нём, пока не истечёт время и выполняется условие.
- Работы могут находиться на разных уровнях.
- Скриптовая зона СТ теперь не используется для захвата персонажей.
- Симуляция заключается в миграции персонажей между разными СТ.
Allowing characters to enter certain ST
Permissions for characters to enter sertain STs are set in the [smart_terrains] section. In it you can set pairs ST_name = condlist, such as:
[smart_terrains] strn_1 = condition1 strn_2 = condition2
If a condition is met for some smart terrain, it is called exclusive.
If a character has at least one exclusive smart terrain, then he will only agree to go to that one.
If he has no exclusive ones, he will agree to go to any.
There is a reserved combination none=true. If it is set, then the character will not go to any ST. This character will only rely on his own logic.
It is also possible to specify who is accepted by a ST. In addition to the old mechanism (function checkNpc() in files gulag_*.script) you can write in custom data for ST:
communities = group1, group2, ...
If this field is not set, then the old mechanism is used. If it is set, then the ST will only accept characters from the specified groups (but the old mechanism will also be called).
Modifying predicate() functions
В эти функции вместо game_object будет передаваться табличка с информацией о персонаже. Там есть поля: name community class_id story_id profile_name
Если нужно, чтобы работа занималась только снайперами, то в предикате нужно писать:
predicate = function(npc_info) return npc_info.is_sniper == true end
Online and offline work modes
t = { section = "logic@ЧЧЧЧЧЧЧЧ", idle = 0, prior = 5, state = {0}, squad = squad, group = groups[1], online = true, in_rest = "", out_rest = "" } table.insert(sj, t)
Options for this field:
- online = true
- the character is always online on this job
- online = false
- the character is always offline on this job
- online not set
- the character might switch between online and offline as deems appropriate
A more accessible description of smart terrains
Now, smart terrains for designers. That is, no LUA, just plain English.
To move a smart terrain to a new scheme, do the following:
- Change inside custom data [gulag1] -> [smart_terrain]
-
In custom data of comrades by smart terrain write:
[smart_terrains] sar_monolith_sklad(gulag name) = {condition list} [smart_terrains] none = true
Helicopter logic
General information
- The helicopter has "logic"
- The helicopter does not react to anomalies
- The helicopter cannot collide with level geometry until shot down
- Hits in the area of the cabin in which the first pilot sits are dozens of times more damaging for the helicopter
- Like stalkers, the helicopter has an all-purpose combat scheme
- Helicopter pilots have replicas for the following events: hit, enemy sited, damaged (smoking), falling.
heli_move scheme
Общие сведения: Позволяет летать вертолёту по патрульному пути, регулировать скорость, зависать, стрелять по различным целям.
Для схемы должен быть задан path_move – путь, по которому будет летать вертолёт. Он может содержать одну вершину, если нужно, чтоб вертолёт висел на месте.
Можно (но не обязательно) задать path_look – путь, в вершины которого вертолет может смотреть.
Вершины этих путей могут быть поставлены где угодно в пределах ограничивающего бокса уровня. Они не зависят от ai-nodes.
По пути вертолёт летает без учёта связей между вершинами. Он летает от вершины к вершине в порядке возрастания их номера (т.е. в порядке, в котором их поставили на уровень).
Вертолёт старается летать точно по вершинам пути. При желании можно сделать ювелирный пролёт под мостом.
Вертолёт старается летать как можно быстрее. Пояснение: если ему задать, что в следующей вершине пути он должен иметь скорость 10 м/с, а его максимальная скорость установлена в 30 м/с, то он не станет сразу лететь 10 м/с. Он сначала будет разгоняться вплоть до 30 м/с и только на подлёте к целевой вершине начнёт тормозить с расчётом прибыть в неё имея 10 м/с.
Если в вершине пути path_move задан набор флажков, то вертолёт будет смотреть в любую из вершин path_look, в которых задан такой же набор флажков. Поворачиваться к этой точке вертолёт начнёт с предыдущей вершины пути. На данном этапе вертолет не может, зависнув в одном месте, смотреть поочередно в несколько точек path_look
Settings:
- engine_sound = true/false (по умолчанию true)
Вкл/выкл звук двигателя вертолёта. - invulnerable = true/false (по умолчанию false)
Неуязвимость. Если true, вертолёт игнорирует все хиты. - immortal = true/false (по умолчанию false)
Бессмертие. Если true, вертолёт получает повреждения, но не умирает. - mute = true/false (по умолчанию false)
Отключает универсальные реплики пилотов вертолета. - rocket_delay = msec (время в миллисекундах реального времени)
Задержака между пусками ракет. По дефолту берется из ltx (сейчас 1250 мсек) - default_velocity = m/sec (скорость с которой летает вертолет, если не заданы другие параметры)
Параметры, задаваемые в именах вершин пути path_move:
- «e» – (сокр. от enemy) задание врага (цели). Стрелять по этой цели вертолёт начнёт уже в предыдущей вершине. Если значение не задано, то будет стрелять в точку из path_look, которая соответствует данной вершине. Если задано «e=actor» (можно сокращённо «e=a»), то огонь будет вестись по актёру. Если задано «e=число», стрелять будет по объекту со story id равным числу.
- «w» – (сокр. от weapon) каким оружием стрелять. Возможные значения: w=1 – стрелять только пулемётом; w=2 – стрелять только ракетами. По умолчанию стреляет из всего.
- «v» - (сокр. от velocity) задание максимальной скорости (в м/с) на участке пути от данной вершины до следующей. Если этот параметр не задан, то умолчание берётся из файла helicopter.ltx.
- «dv» - (сокр. от destination velocity) задание скорости (в м/с), которую вертолёт должен иметь в момент прибытия в данную вершину.
- «die» - убить вертолёт.
- «flame» - начать дымить (как будто подбили).
Параметры, задаваемые в именах вершин пути path_look:
- «e» - работает так же как и в path_move. Разница в том, что стрелять по указанной цели вертолёт начнёт лишь тогда, когда прибудет в вершину пути path_move, которая соответствует данной вершине path_look.
- «w» – см. такой же параметр для пути path_move.
- «t» - (сокр. от time) длительность времени (в мс реального времени), на протяжении которого вертолёт будет смотреть в данную точку. Если этот параметр не задан, то вертолёт пронесётся без остановки, но постарается на ходу развернуться к этой вершине.
All-purpose combat scheme
General information
In the general combat scheme, a helicopter is not tied to a path.
The helicopter does not see anyone. The helicopter can only find someone upon recieval of damaged or from a parameter in custom data.
The helicopter shoots at an enemy upon detection. Until then, looks for him, circling the points of last citings. If it does not see the enemy for a long time — forgets him. If the enemy is specified in the current behavior section, he will not be forgotten while the section is in effect.
Settings
There is no separate section for this behavior scheme. Therefore, settings are given in the current behavior scheme:
- combat_ignore = true/false
- true means ignore hits. That is, the helicopter will not try to "take revenge" on whoever hits it.
- combat_enemy = nil/actor/StoryID
- This parameter could be used to give the helicopter a specific enemy:
- nil
- no enemy
- actor
- player
- SID
- id number of the enemy
- combat_use_rocket = true/false
- Whether the helicopter is authorized to use rockets.
- combat_use_mgun = true/false
- Whether the helicopter is authorized to use the machine gun
- combat_velocity = <число>
- Speed in m/s at which the helicopter will circle.
- combat_safe_altitude = <число>
- Height, relative to the highest point of the geometry of the level, below which the helicopter will not decend (can be negative)
The helicopter has the xr_hit scheme. It words the same way as for stalkers. There is a group of functions for working with a helicopter and its custom data in xr_effects:
- heli_set_enemy_actor
- make the actor the helicopter's enemy
- heli_start_flame
- set the helicopter on fire
- heli_die
- destroy the helicopter
Meet_manager
Синтаксис:
[logic] meet = meet [walker] meet = meet [meet] meet_state = 30| state@sound| 20| state@sound| 10| state@sound meet_state_wpn = 30| state@sound| 20| state@sound| 10| state@sound victim = 30| nil| 20| actor victim_wpn = 30| nil| 20| actor use = self use_wpn = false zone = name| state@sound meet_dialog = dialog_id synpairs = state@sound|state@sound abuse = true/false
Вся настройка встречи отныне будет производится в отдельной секции. В секции logic или в текущей схеме можно будет указать, какую именно секцию с настройкой нужно использовать. Секция, которая указана в секции logic будет влиять на обработку встречи свободногулящим сталкером.
Field list:
- meet_state, meet_state_wpn – задает анимацию и озвучку персонажа, в зависимости от расстояния до актера. Для случая если актер безоружен либо вооружен соответственно.
- victim, victim_wpn – задает объект, на который должен будет смотреть персонаж. Возможные параметры: nil – никуда не смотрит, actor – смотрит на игрока, story_id – номер стори айди персонажа, на которого нужно будет смотреть.
- use, use_wpn – настройки юзабельности персонажа. Возможны три варианта: true, false, self. При self НПС сам юзнет игрока, как только сможет дотянуться
- zone – Содержит набор имен рестрикторов, а также анимаций и озвучки, которую НПС будет отыгрывать, если игрок будет замечен в рестрикторе
- meet_dialog – стартовый диалог НПС.
- synpairs – cодержит набор пар состояние_тела@звуковая_тема. Если при каком то наборе условий встреча будет отыгрывать именно это состояние и эту звуковую тему – то они будут синхронизироваться по рандомным анимациям состояния тела.
- аbuse – по умолчанию true, если false, то неюзающийся противник не будет обижаться.
Любую строку(в общей схеме они написаны строчными буквами) можно задавать кондлистом. ( {+info1 –info2} ward %+info% )
Для облегчения настройки встречи сделана возможность упрощенного задания дефолта:
[walker] meet = default_meet
Саму секцию [default_meet] задавать не надо. Все настройки и так возьмутся из дефолта.
Теперь о том, как с помощью этого конструктора собрать ту реакцию на актера, которая вам нужна (Во всех примерах зеленым цветом выделены состояния state_manager, синим – звуковые темы):
Ситуация 1 Игрок вдалеке подзывает нас рукой, при приближении просит убрать оружие, потом согласен говорить.
[meet] meet_state = 50| hello@talk_hello| 20| wait@wait| 10| ward@wait meet_state_wpn = 50| hello@talk_hello| 20| threat@threat_weap victim = 50| actor victim_wpn = 50| actor use = true use_wpn = false
Ситуация 2 Сталкер завидя нас просит убрать оружие. После этого подходит и заговаривает с нами. Если мы начинаем уходить от него или достаем оружие – начинает нас стрелять.
[meet] meet_state = 50| {+info} threat_fire %= killactor%, walk@ {+info} talk_abuse, wait | 10 | walk %+info%; wait | 2 | threat;state meet_state_wpn = 50| {+info} threat_fire %= killactor%, threat@ {+info} talk_abuse, wait victim = 50| actor victim_wpn = 50| actor use = {-info2} self, false use_wpn = false
Here: info – инфоропшн, который указывает что мы уже опустили оружие и были достаточно близко к НПС Info2 – инфопоршн, который устанавливается в диалоге и говорит что персонаж уже сказал нам все, что хотел. Killactor – функция в xr_effects которая обижает НПС на игрока.
Ситуация 3 Персонаж ходит по патрульному пути на заставе лагеря. Если игрок имеет допуск в лагерь – пропускает его и здоровается, иначе сперва отпугивает, а если игрок пробрался в лагерь – то обижается на него. При этом диалог зависит от того, имеет игрок допуск в лагерь или нет.
[camper] path_walk = path_walk path_look = path_look meet = meet [meet] meet_state = 30| {+info} wait, threat@ {+info} talk_hello, threat_back meet_state_wpn = 30| {+info} wait, threat@ {+info} talk_hello, threat_back victim = 30| actor victim_wpn = 30| actor use = true use_wpn = true zone = warnzone| {-info} threat@ {-info} threat_back|kampzone| {-info} true@ {-info} talk_abuse meet_dialog = {+info} dialog1, dialog2
Here:
- True – вместо анимации, атаковать игрока.
- Info – Инфопоршн, который говорит что мы имеем допуск к лагерю
- Warnzone – рестриктор, в котором нас предупреждают
- Kampzone – рестриктор, в котором нас убивают
- Dialog1 – стартовый диалог НПС, если мы имеем допуск в лагерь
- Dialog2 – стартовый диалог НПС, если мы не имеем допуск в лагерь.
Дефолтные настройки:
По дефолту встреча настроена со следующими параметрами:
meet_state = 30|hello@hail|20|wait@wait meet_state_wpn = 30|backoff@threat_weap victim = 30|actor victim_wpn = 30|actor use = true use_wpn = false syndata = hello@hail|backoff@threat_weap
NB: Если нужно, чтобы сталкер не разговаривал с игроком в данной секции, необходимо прописать ему meet = no_meet
Minimap marks
There is a way to avoid showing stalkers on the minimap and the map (hide blue and red dots). For this, the logic section or the current scheme should have the parameter:
[camper]
- show_spot = false
- to hide stalkers in this section
[walker]
- show_spot = {+info1} false
- a stalker will be hidden if he has infoportion info1
Function arguments
Ниже перечислен набор функций к которым можно обращаться из кастом даты и при этом передавать в них переменные.
NB! Во всех функциях xr_conditions и xr_effects, которые обращались к гулагам по имени, теперь можно использовать как имя, так и story id. Причем если мы указываем имя, то использовать функцию можно только, когда гулаг находится в онлайне, а если мы вешаем на самрттеррейн story_id, то можем обращаться к гулагу и в оффлайне.
Описание функций с параметрами присутствующих в xr_conditions и xr_effects.
xr_conditions:
- fighting_dist_ge(p) – универсальная функция для combat_ignore, проверка расстояния для игрока (в метрах)
- distance_to_obj_le(sid:dist) - проверка дистанции до обьекта заданного story_id.
Можно использовать, например, в секции follower для определения того, что сталкер подошел на нужную дистанцию к лидеру и переключать в другую секцию (лидер при этом стоит где-то в ремарке). Эта ситуация возникает, когда после боя надо подогнать одного сталкера к другому, а ихних позиций мы не знаем. Если используется в секции follower, то dist надо ставить большим distance фолловера, поскольку если поставить их одинаковыми, то данная функция не всегда будет срабатывать. - health_le(health) - проверка того, что здоровье npc <= health
- heli_health_le(health) - аналогично предыдущему, только для вертолета.
- enemy_group(group1:group2:...) - Проверка на принадлежность врага к одной из групп (правильность работы пока не проверялась)
- hitted_by(sid1:sid2:...) - Проверка того, что удар был нанесен кем-то из npc, указанных в списке. npc задаются с помощью story_id. Функцию удобно использовать в секции hit.
Example:
[hit] on_info = {=hitted_by(407:408)} %+val_escort_combat%
killed_by(sid1:sid2:...) - Аналогично предыдущему, но для случая смерти npc. Используется в секции death.
is_alive(sid) is_alive_one(sid1:sid2:...) is_alive_all(sid1:sid2:...) - проверка того, что один, один из нескольких или все из списка соответственно npc, заданные по story_id живы
is_dead(sid) is_dead_one(sid1:sid2:...) is_dead_all(sid1:sid2:...) - аналогично предыдущему, только проверка на "мертвость".
check_fighting(sid1:sid2:...) - Проверка того, не является ли кто-то из перечисленных (с помощью story_id) npc врагом даного. Как правило используется в combat_ignore_cond.
gulag_empty(gulag_name) - проверка того, что гулаг пуст или вообще не существует.
gulag_population_le(gulag_name, num) - проверка того, что количество народу в гулаге <= num
gulag_casualities_ge(gulag_name:num) – проверка того, что гулаг понес потери => num NB! Потери гулага не обнуляются, так что с этой функцией работать аккуратно.
signal(строка) – проверяет, установлен ли у данного НПС в текущей схеме указанный сигнал
xr_effects:
heli_set_enemy(story_id) – сделать npc с указанным story_id врагом веротелу. В одной секции можно задавать только 1 врага.
set_gulag_enemy_actor(gulag_name) – сделать актера врагом для данного гулага
hit_npc(direction:bone:power:impulse:reverse=false) - нанести хит по npc. Параметры:
- direction - если строка, то считается, что это имя пути и в сторону первой точки производится толчек. Если же это число, то оно рассматривается как story_id персонажа от которого должен поступить хит.
- bone - строка. Имя кости, по которой наносится удар.
- power - сила удара
- impulse - импульс
- reverse (true/false) - изменение направления удара на противоположное. по умолчанию false.
Example:
[death] on_info = {=killed_by(404)} %=hit_npc(404:bip01_spine1:100:2000)%, {=killed_by(405)} %=hit_npc(405:bip01_spine1:100:2000)%
set_friends(sid1:sid2:...) set_enemies(sid1:sid2:...) - установить друзьями/врагами данного npc и указанных в списке по story_id.
play_snd(snd_name:delay=0) - играть звук в голове актёра.
- snd_name - путь к звуку относительно папки sounds
- delay - задержка перед проигрыванием. По умолчанию 0 – проигрываем сразу.
play_snd_now (sid:snd_name) – играть звук от указанного объекта
- звук играется об объекта с указанным story id, без задержки с громкостью 1. Указывается не имя звуковой схемы, а имя файла
hit_obj(sid, bone, power, impulse, hit_src=npc:position()) Дать обьекту, заданому story_id, хит. Отличается тем, что может прописываться в любой кастом дате. Параметры: actor, npc, p[sid,bone,power,impulse,hit_src=npc:position()]
- sid - story_id обьекта, по которому наносится хит.
- bone - строка. Имя кости, по которой наносится удар.
- power - сила удара
- impulse - импульс
- hit_src (необязательный параметр) - точка (waypoint), из которой по объекту наносится хит. Если не задано, то берется позиция обьекта, из которого была вызвана данная функция.
actor_has_item(section) Проверка на наличие у игрока соответствующего предмета. Проверка проходит по секции в ltx
Функции для работы с HUD'ом.
disable_ui_elements(...), enable_ui_elements(...) - отключение/включение елементов HUD'а.
Параметры:
- weapon - спрятать/показать руки с оружием
- input - отключить/включить клавиатуру
- hud - спрятать/показать индикаторы на экране
- all - отключить/включить все элементы
Example:
on_info = %=disable_ui_elements(weapon:input)%
Есть также сокращенные варианты:
disable_ui, enable_ui (вызываются без скобок и параметров). Аналогичны вызовам disable_ui_elements(all), enable_ui_elements(all) соответственно.
Example:
on_info = %=enable_ui%
Функция запуска camera_effector'а.
run_cam_effector(имя_файла)
имя_файла (указывается без расширения) - это имя анимационного файла (с расширением anm) из папки S:\GameData\anims\camera_effects\.
Example:
on_info = %=run_cam_effector(prison_0)%
Функция запуска постпроцесса.
В связи с изменением процесса создания постпроцессов были внесены изменения в их запуск. Теперь есть 2 функции для работы с постпроцессами:
run_postprocess(file_name:id:loop) - запуск постпроцесса.
- file_name - имя файла постпроцесса (без расширения) из папки s:\gamedata\anims. Указывается без расширения.
- id - номер постпроцесса. Задается опционально. Используется в stop_postprocess.
- loop - (true/false) определяет зацикленность постпроцесса. Опциональный параметр. По умолчанию false.
- stop_postprocess(id) - принудительная остановка постпроцесса.
- id - номер постпроцесса заданный в run_postprocess.
Функция выброса содержимого инвентаря актера в определенную точку.
drop_actor_inventory(имя_пути)
выбрасываем все предметы из инвентаря актера в первую точку заданного пути.
Example:
on_info = %=drop_actor_inventory(drop_point)%
Sound group configuration
The way to create sound groups:
- Each character is considered to be in a unique soundgroup by default.
- To put several characters into a single sound group, the logic section of each one must contain soundgroup = <text string>
- Sound groups must be unique within each level, or, better yet, within the whole game. For this, add level and scene identifiers to the name of the group, as in: soundgroup = bar_dolg_kampfire1.
- Characters sitting at a camp or walking together in patrol groups or in such similar situations should be put into sound groups.
- To avoid errors, all NPCs logically belonging to a group should have the same team, squad, group.
Example:
[kamp@esc_bridge_post1] center_point = kamp_point soundgroup = esc_bridge_soldiers
Author
GSC Game World