Вторник, 14.07.2020, 10:53 Приветствую Вас Гость

Меню сайта
Обновления
Категории раздела
Облако тегов
Главная » Статьи » Модострой [ Добавить статью ]

Создание телепорта
В игре существует такой объект как "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) 
Создаст телепорт возле выхода из бункера Сидоровича. Наш телепорт перебрасывает игрока на вышку блокпоста (перед выходом с уровня).
Категория: Модострой | Добавил: cTpeJIok (12.08.2010) | Автор: илья
Просмотров: 1665 | Комментарии: 1 | Рейтинг: 5.0/1
Всего комментариев: 1
0
1 snork   [Материал]
что такое create? напишите подробней!

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Профиль
Гость

СТРАННИК!
Мы всегда рады видеть
еще одну живую душу!
Но мы незнаем кто ты?
Регистрация
Поиск по сайту
Опросы
Ваш возраст
Всего ответов: 1266
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Авторское право на мод принадлежит AMI - ALEX MOD INFERNO
Любое использование материалов мода возможно, если в ваших материалах будет копирайт AMI - ALEX MOD INFERNO