Среда, 14.01.2026, 05:26
Приветствую Вас Гость | RSS
F.R.O.N.T.
Главная | Статьи | Регистрация | Вход
Меню сайта
Все новые статьи находяться на форуме!!! Видеть их могут только рарегистрированые пользователи...
Категории каталога
Мои статьи [28] Сценарии [0]
Пишите сюда свои сцинарии
Модострой [152]
Статьи по созданию модов
КАК СНЯТЬ ФИЛЬМ??? [0]
Статьи о том как снять фильмы
Мини-чат
Наш опрос
Чего не хватает в сталкере
1. Возможностей
2. Группировок
3. Свободы
4. Квестов
5. Транспорта
6. Ничего, все есть
7. Мутантов
8. Оружия
9. Атмосферы
10. Блин, сталкер отстой
11. Брони
12. Графики
13. Аномалий
14. Артефактов
15. Предметов
Всего ответов: 155
Главная » Статьи » Модострой

Создание телепорта
Содержание
1 Создаем телепорт
1.1 Теория этого дела
1.2 Реализация
1.3 Использование
2 Авторы

Создаем телепорт
Теория этого дела

В игре существует такой объект как "zone_teleport", но если мы его создадим через create, то он будет выглядеть и переливаться как настоящий телепорт, но телепортировать нас куда-либо увы не сможет. Связано это с тем что, у аномалий ( а телепорт это такая разновидность аномалии ) параметры задаются хитромудро, через all.spawn. Вобщем штатным способом телепорты без полнофункционального редактора карт не получить (хотя возможно я не прав уже после написания этого текста появились идеи как это сделать через all.spawn). Значит на нашу долю остаються способы "не штатные" ;) Реализуем самый простой. Будем считать что у нас на карте есть квадрат с заданными координатами при попадании в который актера должно переместить в точку с другими координатами. Для этого будем периодически проверять координаты актера, и если он в квадрате - перемещяем. Вот в краце принцип действия нашего "самодельного" телепорта.
Реализация

В каталоге gamedata\scripts\ Создадим файл bind_mteleport.script с логикой работы нашего телепорта.
-- ************************************************
-- ** Imp **
-- ** Биндер самодельных телепортов **
-- ** Поддерживает работу самопальных телепортов **
-- ************************************************

local teleport_binders ={} -- Список телепортов

function abs_comp(a,b)
-- Служебная функция вычисления разности
if( a < b) then
return (b - a)
else
return (a - b)
end
end

function teleportate(x,y,z)
-- Функция телепортации
local a = vector()
-- Задаем координаты
a.x = x
a.y = y
a.z = z

-- Сама телепортация
db.actor:set_actor_position(a)

-- Звуковое сопровождение
local snd_obj = xr_sound.get_safe_sound_object([[affects\tinnitus3a]])
snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 1.0)

end


function actor_update(delta)
local i,v,acter_poz,s

-- Получим позицию актера (что-бы каждый раз не запрашивать)
acter_poz = db.actor:position()

-- Проверяем наши телепорты
for i, v in pairs(teleport_binders) do
s = v.parametrs

local obj = level.object_by_id( i )
if obj ~= nil then
-- Наш телепорт в онлайне проверяем дальше
if s.teleporte ~= nil and s.teleporte ~= false then
-- Телепорт запущен
if ( time_global() <= s.time ) then
-- Если время отведенное на показ спецэфектов
-- прошло, производим телепортацию
teleportate(s.poz_x,s.poz_y,s.poz_z)
if s.rotate ~= nil then
db.actor:set_actor_direction(s.rotate)
end
s.teleporte = false
end
return
end

-- Пороверим не забрел-ли актер в наш телепорт
if (abs_comp(s.x, acter_poz.x)< v.parametrs.radius and
abs_comp(s.z, acter_poz.z)< v.parametrs.radius and
abs_comp(s.y, acter_poz.y)< v.parametrs.z_radius) then
-- Актер в зоне действия телепорта, запустим телепорт
s["teleporte"] = true
s["time"] = time_global() + 500

-- Запускаем спецэфекты телепортации
level.add_pp_effector ("teleport.ppe", 2006, false)
end
end
end
end

function bind( obj )
obj:bind_object( restrictor_teleport( obj ) )
end

----------------------------------------------------------------------------------------------------
class "restrictor_teleport" ( object_binder )

function restrictor_teleport:__init(obj, char_ini) super(obj)
end

function restrictor_teleport:net_spawn(data)
local char_ini = system_ini()

-- Если это телепорт то занесем его в специальный список телепортов
if self.teleport == true then
teleport_binders[self.object:id()] = self

-- Заполним таблицу параметров
self["parametrs"] = {}
if char_ini:line_exist(self.section, "radius") then
self.parametrs["radius"] = tonumber(char_ini:r_string(self.section, "radius"))
else
self.parametrs["radius"] = 2 -- Дефолтный радиус по xy
end
if char_ini:line_exist(self.section, "z_radius") then
self.parametrs["z_radius"] = tonumber(char_ini:r_string(self.section, "z_radius"))
else
self.parametrs["z_radius"] = self.parametrs["radius"] -- если радиус высоты не задан то задаем равным радиусу xy
end

-- Запомним позицию что-бы каждый раз не считать
local s_obj = alife():object(self.object:id())
self.parametrs["x"] = tonumber(s_obj.position.x);
self.parametrs["y"] = tonumber(s_obj.position.y);
self.parametrs["z"] = tonumber(s_obj.position.z);

-- Запомним координаты куда телепортимся
self.parametrs["poz_x"] = tonumber(char_ini:r_string(self.section, "poz_x"))
self.parametrs["poz_y"] = tonumber(char_ini:r_string(self.section, "poz_y"))
self.parametrs["poz_z"] = tonumber(char_ini:r_string(self.section, "poz_z"))

if char_ini:line_exist(self.section, "rotate") then
self.parametrs["rotate"] = tonumber(char_ini:r_string(self.section, "rotate"))
end
end
return true
end

function restrictor_teleport:net_destroy()
-- Удаляем наш телепорт
teleport_binders[self.object:id()] = nil
self.parametrs = nil
object_binder.net_destroy(self)
end

function restrictor_teleport:reload(section)
local char_ini = system_ini()

self.section = section
-- Если это телепорт то
if char_ini ~= nil and char_ini:line_exist(self.section, "teleport") then
self["teleport"] = true
end
end


Для постоянного обновления нужно прицепить функцию actor_update() к биндеру актера, для чего в файле bind_stalker.script найдем функцию:

function actor_binder:update(delta)

В ней найдем вызов обновления рестрикторов bind_restrictor.actor_update(delta) под которым вставим строку с вызовом нашей функции обновления: bind_mteleport.actor_update(delta)

Все с программной частью закончили, теперь задаем данные телепорта.

В каталоге gamedata\config\misc открываем файл zone_teleport.ltx и в конце файла добавляем следующие строки описывающие конкретный телепорт:
[m_teleport_1]:zone_teleport
teleport = standart
script_binding = bind_mteleport.bind
;Параметры нашего телепорта
radius = 2
;Высота захвата телепорта
z_radius = 2

;Куда телепортируемся (телепортация всегда идет в пределах карты)
poz_x = 22.78
poz_y = 20.35
poz_z = 659.24

; Угол зрения при появлении. Если параметра нет то не меняется.
rotate = 1.5

Параметры нашего телепорта:
radius - на самом деле не радиус, а половина длинны стороны нашего квадрата (в начале я хотел сделать его кругом, но посчитал, что лучше не тратить процессорное врямя по пусту). Центром квадрата является точка респавна телепорта.
z_radius - высота нашего телепорта.
poz_x, poz_y, poz_z - координаты точки телепортации.
rotate - Угол поворота после телепортации от оси X (я не разбирался в каких единицах задается, но 1.5 примерно равно 90 градусов). Если параметр удалить то будет оставатья угол под которым актер вошел в телепорт.
Использование

Теперь с помощью create создадим наш телепорт: Пример:
local obj
local a = vector()
a.x = -244.55
a.y = -19.46
a.z = -125.42
obj = alife():create("m_teleport_1",a,12829,8,65535)

Создаст телепорт возле выхода из бункера Сидоровича. Наш телепорт перебрасывает игрока на вышку блокпоста (перед выходом с уровня).

Все! Вот тут вы можете взять готовый мод с двумя телепортами.
Авторы

Статья создана:
Imp


Категория: Модострой | Добавил: front (20.09.2008)
Просмотров: 2127 | Рейтинг: 5.0/1 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа
Поиск
счетчик посещенийсчетчик посещений
Друзья сайта
 
Фан сайт игры S.T.A.L.K.E.R.

Бар_У_границы_Зоны_бар_настоящего_сталкера!

Статистика

На портале: 1
Новичков: 1
Участников: 0

Copyright MyCorp © 2026